From 8d2d8dc26727a5b46613d83522490f568aef7cad Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 11 Jun 2021 14:51:29 +0200 Subject: Enable toggling tags --- src/timeline/RoomlistModel.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 4dd44b30..c0fb74a4 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -324,6 +324,7 @@ RoomlistModel::initializeRooms() models.clear(); roomids.clear(); invites.clear(); + currentRoom_ = nullptr; invites = cache::client()->invites(); for (const auto &id : invites.keys()) @@ -461,6 +462,22 @@ FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &righ return left.row() < right.row(); } +bool +FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const +{ + if (filterType == FilterBy::Nothing) + return true; + else if (filterType == FilterBy::Tag) { + auto tags = sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + return tags.contains(filterStr); + } else { + return true; + } +} + FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *parent) : QSortFilterProxyModel(parent) , roomlistmodel(model) -- cgit 1.5.1 From a5291605a9912a411100edf8ee88e59857d8b9aa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 11 Jun 2021 17:54:05 +0200 Subject: Reenable tag hiding --- resources/qml/CommunitiesList.qml | 10 +++--- src/timeline/CommunitiesModel.cpp | 30 ++++++++++++++++- src/timeline/CommunitiesModel.h | 4 +++ src/timeline/RoomlistModel.cpp | 65 +++++++++++++++++++++++++++--------- src/timeline/RoomlistModel.h | 3 ++ src/timeline/TimelineViewManager.cpp | 4 +++ 6 files changed, 94 insertions(+), 22 deletions(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml index 0ccd7e82..6aab949c 100644 --- a/resources/qml/CommunitiesList.qml +++ b/resources/qml/CommunitiesList.qml @@ -33,16 +33,16 @@ Page { Platform.Menu { id: communityContextMenu - property string id + property string tagId function show(id_, tags_) { - id = id_; + tagId = id_; open(); } Platform.MenuItem { - text: qsTr("Leave room") - onTriggered: Rooms.leave(roomContextMenu.roomid) + text: qsTr("Hide rooms with this tag or from this space by default.") + onTriggered: Communities.toggleTagId(communityContextMenu.tagId) } } @@ -65,7 +65,7 @@ Page { states: [ State { name: "highlight" - when: hovered.hovered && !(Communities.currentTagId == model.id) + when: (hovered.hovered || model.hidden) && !(Communities.currentTagId == model.id) PropertyChanges { target: communityItem diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 9b758e97..96a450ea 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -21,6 +21,7 @@ CommunitiesModel::roleNames() const {DisplayName, "displayName"}, {Tooltip, "tooltip"}, {ChildrenHidden, "childrenHidden"}, + {Hidden, "hidden"}, {Id, "id"}, }; } @@ -38,6 +39,8 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return tr("Shows all rooms without filtering."); case CommunitiesModel::Roles::ChildrenHidden: return false; + case CommunitiesModel::Roles::Hidden: + return false; case CommunitiesModel::Roles::Id: return ""; } @@ -82,8 +85,10 @@ CommunitiesModel::data(const QModelIndex &index, int role) const } switch (role) { + case CommunitiesModel::Roles::Hidden: + return hiddentTagIds_.contains("tag:" + tag); case CommunitiesModel::Roles::ChildrenHidden: - return UserSettings::instance()->hiddenTags().contains("tag:" + tag); + return true; case CommunitiesModel::Roles::Id: return "tag:" + tag; } @@ -107,9 +112,12 @@ CommunitiesModel::initializeSidebar() tags_.clear(); for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); + + hiddentTagIds_ = UserSettings::instance()->hiddenTags(); endResetModel(); emit tagsChanged(); + emit hiddenTagsChanged(); } void @@ -158,3 +166,23 @@ CommunitiesModel::setCurrentTagId(QString tagId) this->currentTagId_ = ""; emit currentTagIdChanged(currentTagId_); } + +void +CommunitiesModel::toggleTagId(QString tagId) +{ + if (hiddentTagIds_.contains(tagId)) { + hiddentTagIds_.removeOne(tagId); + UserSettings::instance()->setHiddenTags(hiddentTagIds_); + } else { + hiddentTagIds_.push_back(tagId); + UserSettings::instance()->setHiddenTags(hiddentTagIds_); + } + + if (tagId.startsWith("tag:")) { + auto idx = tags_.indexOf(tagId.mid(4)); + if (idx != -1) + emit dataChanged(index(idx), index(idx), {Hidden}); + } + + emit hiddenTagsChanged(); +} diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index 038c253b..c98b5955 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -25,6 +25,7 @@ public: DisplayName, Tooltip, ChildrenHidden, + Hidden, Id, }; @@ -49,12 +50,15 @@ public slots: emit currentTagIdChanged(currentTagId_); } QStringList tags() const { return tags_; } + void toggleTagId(QString tagId); signals: void currentTagIdChanged(QString tagId); + void hiddenTagsChanged(); void tagsChanged(); private: QStringList tags_; QString currentTagId_; + QStringList hiddentTagIds_; }; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index c0fb74a4..0f980c6c 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -462,22 +462,6 @@ FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &righ return left.row() < right.row(); } -bool -FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const -{ - if (filterType == FilterBy::Nothing) - return true; - else if (filterType == FilterBy::Tag) { - auto tags = sourceModel() - ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) - .toStringList(); - - return tags.contains(filterStr); - } else { - return true; - } -} - FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *parent) : QSortFilterProxyModel(parent) , roomlistmodel(model) @@ -502,6 +486,55 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare sort(0); } +void +FilteredRoomlistModel::updateHiddenTagsAndSpaces() +{ + hiddenTags.clear(); + hiddenSpaces.clear(); + for (const auto &t : UserSettings::instance()->hiddenTags()) { + if (t.startsWith("tag:")) + hiddenTags.push_back(t.mid(4)); + else if (t.startsWith("space:")) + hiddenSpaces.push_back(t.mid(6)); + } + + invalidateFilter(); +} + +bool +FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const +{ + if (filterType == FilterBy::Nothing) { + if (!hiddenTags.empty()) { + auto tags = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + for (const auto &t : tags) + if (hiddenTags.contains(t)) + return false; + } + + return true; + } else if (filterType == FilterBy::Tag) { + auto tags = sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + if (!tags.contains(filterStr)) + return false; + else if (!hiddenTags.empty()) { + for (const auto &t : tags) + if (t != filterStr && hiddenTags.contains(t)) + return false; + } + return true; + } else { + return true; + } +} + void FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on) { diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index b89c9a54..b0244886 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -142,6 +142,8 @@ public slots: invalidateFilter(); } + void updateHiddenTagsAndSpaces(); + signals: void currentRoomChanged(); @@ -158,4 +160,5 @@ private: }; QString filterStr = ""; FilterBy filterType = FilterBy::Nothing; + QStringList hiddenTags, hiddenSpaces; }; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 2ee79d4f..c109d38e 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -201,6 +201,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par &CommunitiesModel::currentTagIdChanged, ptr, &FilteredRoomlistModel::updateFilterTag); + connect(self->communities_, + &CommunitiesModel::hiddenTagsChanged, + ptr, + &FilteredRoomlistModel::updateHiddenTagsAndSpaces); return ptr; }); qmlRegisterSingletonType( -- 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/RoomlistModel.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/RoomlistModel.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/RoomlistModel.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 From c69d2ef64886ee4946abf4b959d53b884014ce7a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 18 Jun 2021 14:13:01 +0200 Subject: Fix off by 1 in previousRoom condition --- src/timeline/RoomlistModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index e4014333..a44959fc 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -662,7 +662,7 @@ FilteredRoomlistModel::previousRoom() if (r) { int idx = roomidToIndex(r->roomId()); idx--; - if (idx > 0) { + if (idx >= 0) { setCurrentRoom( data(index(idx, 0), RoomlistModel::Roles::RoomId).toString()); } -- cgit 1.5.1 From f8dfc726255df415aaeb9339b20f83cd265ee303 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 20 Jun 2021 13:30:35 +0200 Subject: Fix spaces showing up with world filter --- src/timeline/RoomlistModel.cpp | 69 +++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index a44959fc..7f59b112 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -531,6 +531,12 @@ bool FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const { if (filterType == FilterBy::Nothing) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; + } + if (!hiddenTags.empty()) { auto tags = sourceModel() @@ -540,7 +546,9 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : tags) if (hiddenTags.contains(t)) return false; - } else if (!hiddenSpaces.empty()) { + } + + if (!hiddenSpaces.empty()) { auto parents = sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) @@ -548,25 +556,30 @@ 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::Tag) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; + } + auto tags = sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) .toStringList(); if (!tags.contains(filterStr)) return false; - else if (!hiddenTags.empty()) { + + if (!hiddenTags.empty()) { for (const auto &t : tags) if (t != filterStr && hiddenTags.contains(t)) return false; - } else if (!hiddenSpaces.empty()) { + } + + if (!hiddenSpaces.empty()) { auto parents = sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) @@ -574,41 +587,47 @@ 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) { + if (filterStr == sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) + .toString()) + return true; + auto parents = sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) .toStringList(); - auto tags = sourceModel() - ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) - .toStringList(); - if (filterStr == sourceModel() - ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) - .toString()) - return true; - else if (!parents.contains(filterStr)) + if (!parents.contains(filterStr)) return false; - else if (!hiddenTags.empty()) { + + if (!hiddenTags.empty()) { + auto tags = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + for (const auto &t : tags) if (hiddenTags.contains(t)) return false; - } else if (!hiddenSpaces.empty()) { + } + + if (!hiddenSpaces.empty()) { 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)) { + } + + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool() && + !parents.contains(filterStr)) { return false; } + return true; } else { return true; -- cgit 1.5.1 From 5b016cbc6843029d62f79602a36203d4a4f9e230 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 1 Jul 2021 12:45:47 +0200 Subject: Remove dead code to calculate last message --- src/Cache.cpp | 92 ------------------------------------------ src/CacheStructs.h | 2 - src/Cache_p.h | 1 - src/timeline/RoomlistModel.cpp | 6 +-- 4 files changed, 3 insertions(+), 98 deletions(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 144a2d9a..aba76406 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1794,8 +1794,6 @@ Cache::roomInfo(bool withInvites) while (roomsCursor.get(room_id, room_data, MDB_NEXT)) { RoomInfo tmp = json::parse(std::move(room_data)); tmp.member_count = getMembersDb(txn, std::string(room_id)).size(txn); - tmp.msgInfo = getLastMessageInfo(txn, std::string(room_id)); - result.insert(QString::fromStdString(std::string(room_id)), std::move(tmp)); } roomsCursor.close(); @@ -2022,96 +2020,6 @@ Cache::getTimelineEventId(const std::string &room_id, uint64_t index) return std::string(val); } -DescInfo -Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) -{ - lmdb::dbi orderDb; - try { - orderDb = getOrderToMessageDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - lmdb::dbi eventsDb; - try { - eventsDb = getEventsDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - lmdb::dbi membersdb; - try { - membersdb = getMembersDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - if (orderDb.size(txn) == 0) - return DescInfo{}; - - const auto local_user = utils::localUser(); - - DescInfo fallbackDesc{}; - - std::string_view indexVal, event_id; - - auto cursor = lmdb::cursor::open(txn, orderDb); - bool first = true; - while (cursor.get(indexVal, event_id, first ? MDB_LAST : MDB_PREV)) { - first = false; - - std::string_view event; - bool success = eventsDb.get(txn, event_id, event); - if (!success) - continue; - - auto obj = json::parse(event); - - if (fallbackDesc.event_id.isEmpty() && obj["type"] == "m.room.member" && - obj["state_key"] == local_user.toStdString() && - obj["content"]["membership"] == "join") { - uint64_t ts = obj["origin_server_ts"]; - auto time = QDateTime::fromMSecsSinceEpoch(ts); - fallbackDesc = DescInfo{QString::fromStdString(obj["event_id"]), - local_user, - tr("You joined this room."), - utils::descriptiveTime(time), - ts, - time}; - } - - if (!(obj["type"] == "m.room.message" || obj["type"] == "m.sticker" || - obj["type"] == "m.call.invite" || obj["type"] == "m.call.answer" || - obj["type"] == "m.call.hangup" || obj["type"] == "m.room.encrypted")) - continue; - - mtx::events::collections::TimelineEvent te; - mtx::events::collections::from_json(obj, te); - - std::string_view info; - MemberInfo m; - if (membersdb.get(txn, obj["sender"].get(), info)) { - m = json::parse(std::string_view(info.data(), info.size())); - } - - cursor.close(); - return utils::getMessageDescription( - te.data, local_user, QString::fromStdString(m.name)); - } - cursor.close(); - - return fallbackDesc; -} - QHash Cache::invites() { diff --git a/src/CacheStructs.h b/src/CacheStructs.h index 1d0f0d70..28c70055 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -83,8 +83,6 @@ struct RoomInfo //! Who can access to the room. mtx::events::state::JoinRule join_rule = mtx::events::state::JoinRule::Public; bool guest_access = false; - //! Metadata describing the last message in the timeline. - DescInfo msgInfo; //! The list of tags associated with this room std::vector tags; }; diff --git a/src/Cache_p.h b/src/Cache_p.h index cfcf9c9e..c76cc717 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -334,7 +334,6 @@ private: std::optional getMember(const std::string &room_id, const std::string &user_id); 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, diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 7f59b112..6a90ab6e 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -116,11 +116,11 @@ RoomlistModel::data(const QModelIndex &index, int role) const case Roles::RoomId: return roomid; case Roles::LastMessage: - return room.msgInfo.body; + return QString(); case Roles::Time: - return room.msgInfo.descriptiveTime; + return QString(); case Roles::Timestamp: - return QVariant(static_cast(room.msgInfo.timestamp)); + return QVariant(static_cast(0)); case Roles::HasUnreadMessages: case Roles::HasLoudNotification: return false; -- cgit 1.5.1 From 9540d704e090d129835ae4f96e0145cb6de07484 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 4 Jul 2021 23:06:50 +0200 Subject: Show previews for space rooms --- src/timeline/RoomlistModel.cpp | 233 ++++++++++++++++++++++++++++++++++++----- src/timeline/RoomlistModel.h | 5 + 2 files changed, 213 insertions(+), 25 deletions(-) (limited to 'src/timeline/RoomlistModel.cpp') diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 6a90ab6e..87940948 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -33,6 +33,27 @@ RoomlistModel::RoomlistModel(TimelineViewManager *parent) &RoomlistModel::totalUnreadMessageCountUpdated, ChatPage::instance(), &ChatPage::unreadMessages); + + connect( + this, + &RoomlistModel::fetchedPreview, + this, + [this](QString roomid, RoomInfo info) { + if (this->previewedRooms.contains(roomid)) { + this->previewedRooms.insert(roomid, std::move(info)); + auto idx = this->roomidToIndex(roomid); + emit dataChanged(index(idx), + index(idx), + { + Roles::RoomName, + Roles::AvatarUrl, + Roles::IsSpace, + Roles::IsPreviewFetched, + Qt::DisplayRole, + }); + } + }, + Qt::QueuedConnection); } QHash @@ -61,6 +82,16 @@ RoomlistModel::data(const QModelIndex &index, int role) const if (index.row() >= 0 && static_cast(index.row()) < roomids.size()) { auto roomid = roomids.at(index.row()); + if (role == Roles::ParentSpaces) { + auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); + QStringList list; + for (const auto &t : parents) + list.push_back(QString::fromStdString(t)); + return list; + } else if (role == Roles::RoomId) { + return roomid; + } + if (models.contains(roomid)) { auto room = models.value(roomid); switch (role) { @@ -68,8 +99,6 @@ RoomlistModel::data(const QModelIndex &index, int role) const return room->roomAvatarUrl(); case Roles::RoomName: return room->plainRoomName(); - case Roles::RoomId: - return room->roomId(); case Roles::LastMessage: return room->lastMessage().body; case Roles::Time: @@ -88,6 +117,8 @@ RoomlistModel::data(const QModelIndex &index, int role) const return false; case Roles::IsSpace: return room->isSpace(); + case Roles::IsPreview: + return false; case Roles::Tags: { auto info = cache::singleRoomInfo(roomid.toStdString()); QStringList list; @@ -95,14 +126,6 @@ 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 {}; } @@ -113,8 +136,6 @@ RoomlistModel::data(const QModelIndex &index, int role) const return QString::fromStdString(room.avatar_url); case Roles::RoomName: return QString::fromStdString(room.name); - case Roles::RoomId: - return roomid; case Roles::LastMessage: return QString(); case Roles::Time: @@ -130,21 +151,77 @@ RoomlistModel::data(const QModelIndex &index, int role) const return true; case Roles::IsSpace: return false; + case Roles::IsPreview: + 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 {}; } + } else if (previewedRooms.contains(roomid) && + previewedRooms.value(roomid).has_value()) { + auto room = previewedRooms.value(roomid).value(); + switch (role) { + case Roles::AvatarUrl: + return QString::fromStdString(room.avatar_url); + case Roles::RoomName: + return QString::fromStdString(room.name); + case Roles::LastMessage: + return tr("Previewing this room"); + case Roles::Time: + return QString(); + case Roles::Timestamp: + return QVariant(static_cast(0)); + case Roles::HasUnreadMessages: + case Roles::HasLoudNotification: + return false; + case Roles::NotificationCount: + return 0; + case Roles::IsInvite: + return false; + case Roles::IsSpace: + return room.is_space; + case Roles::IsPreview: + return true; + case Roles::IsPreviewFetched: + return true; + case Roles::Tags: + return QStringList(); default: return {}; } } else { - return {}; + if (role == Roles::IsPreview) + return true; + else if (role == Roles::IsPreviewFetched) + return false; + + fetchPreview(roomid); + switch (role) { + case Roles::AvatarUrl: + return QString(); + case Roles::RoomName: + return tr("No preview available"); + case Roles::LastMessage: + return QString(); + case Roles::Time: + return QString(); + case Roles::Timestamp: + return QVariant(static_cast(0)); + case Roles::HasUnreadMessages: + case Roles::HasLoudNotification: + return false; + case Roles::NotificationCount: + return 0; + case Roles::IsInvite: + return false; + case Roles::IsSpace: + return false; + case Roles::Tags: + return QStringList(); + default: + return {}; + } } } else { return {}; @@ -248,25 +325,111 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) newRoom->updateLastMessage(); - bool wasInvite = invites.contains(room_id); - if (!suppressInsertNotification && !wasInvite) - beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size()); + std::vector previewsToAdd; + if (newRoom->isSpace()) { + auto childs = cache::client()->getChildRoomIds(room_id.toStdString()); + for (const auto &c : childs) { + auto id = QString::fromStdString(c); + if (!(models.contains(id) || invites.contains(id) || + previewedRooms.contains(id))) { + previewsToAdd.push_back(std::move(id)); + } + } + } - models.insert(room_id, std::move(newRoom)); + bool wasInvite = invites.contains(room_id); + bool wasPreview = previewedRooms.contains(room_id); + if (!suppressInsertNotification && + ((!wasInvite && !wasPreview) || !previewedRooms.empty())) + // if the old room was already in the list, don't add it. Also add all + // previews at the same time. + beginInsertRows(QModelIndex(), + (int)roomids.size(), + (int)(roomids.size() + previewsToAdd.size() - + ((wasInvite || wasPreview) ? 0 : 1))); + models.insert(room_id, std::move(newRoom)); if (wasInvite) { auto idx = roomidToIndex(room_id); invites.remove(room_id); emit dataChanged(index(idx), index(idx)); + } else if (wasPreview) { + auto idx = roomidToIndex(room_id); + previewedRooms.remove(room_id); + emit dataChanged(index(idx), index(idx)); } else { roomids.push_back(room_id); } + for (auto p : previewsToAdd) { + previewedRooms.insert(p, std::nullopt); + roomids.push_back(std::move(p)); + } + if (!suppressInsertNotification && !wasInvite) endInsertRows(); } } +void +RoomlistModel::fetchPreview(QString roomid_) const +{ + std::string roomid = roomid_.toStdString(); + http::client()->get_state_event( + roomid, + "", + [this, roomid](const mtx::events::state::Create &c, mtx::http::RequestErr err) { + bool is_space = false; + if (!err) { + is_space = c.type == mtx::events::state::room_type::space; + } + + http::client()->get_state_event( + roomid, + "", + [this, roomid, is_space](const mtx::events::state::Avatar &a, + mtx::http::RequestErr) { + auto avatar_url = a.url; + + http::client()->get_state_event( + roomid, + "", + [this, roomid, avatar_url, is_space]( + const mtx::events::state::Topic &t, mtx::http::RequestErr) { + auto topic = t.topic; + http::client()->get_state_event( + roomid, + "", + [this, roomid, topic, avatar_url, is_space]( + const mtx::events::state::Name &n, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn( + "Failed to fetch name event to " + "create preview for {}", + roomid); + } + + // don't even add a preview, if we got not a single + // response + if (n.name.empty() && avatar_url.empty() && + topic.empty()) + return; + + RoomInfo info{}; + info.name = n.name; + info.is_space = is_space; + info.avatar_url = avatar_url; + info.topic = topic; + + const_cast(this)->fetchedPreview( + QString::fromStdString(roomid), info); + }); + }); + }); + }); +} + void RoomlistModel::sync(const mtx::responses::Rooms &rooms) { @@ -426,7 +589,9 @@ RoomlistModel::setCurrentRoom(QString roomid) namespace { enum NotificationImportance : short { - ImportanceDisabled = -1, + ImportanceDisabled = -3, + NoPreview = -2, + Preview = -1, AllEventsRead = 0, NewMessage = 1, NewMentions = 2, @@ -448,6 +613,11 @@ FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const return CurrentSpace; else return SubSpace; + } else if (sourceModel()->data(idx, RoomlistModel::IsPreview).toBool()) { + if (sourceModel()->data(idx, RoomlistModel::IsPreviewFetched).toBool()) + return Preview; + else + return NoPreview; } else if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) { return Invite; } else if (!this->sortByImportance) { @@ -460,6 +630,7 @@ FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const return AllEventsRead; } } + bool FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { @@ -531,6 +702,12 @@ bool FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const { if (filterType == FilterBy::Nothing) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview) + .toBool()) { + return false; + } + if (sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) .toBool()) { @@ -560,6 +737,12 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons return true; } else if (filterType == FilterBy::Tag) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview) + .toBool()) { + return false; + } + if (sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) .toBool()) { diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index d6cbb462..2005c35e 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -37,6 +37,8 @@ public: NotificationCount, IsInvite, IsSpace, + IsPreview, + IsPreviewFetched, Tags, ParentSpaces, }; @@ -87,15 +89,18 @@ private slots: signals: void totalUnreadMessageCountUpdated(int unreadMessages); void currentRoomChanged(); + void fetchedPreview(QString roomid, RoomInfo info); private: void addRoom(const QString &room_id, bool suppressInsertNotification = false); + void fetchPreview(QString roomid) const; TimelineViewManager *manager = nullptr; std::vector roomids; QHash invites; QHash> models; std::map roomReadStatus; + QHash> previewedRooms; QSharedPointer currentRoom_; -- cgit 1.5.1