Add space notifications to room list

This commit is contained in:
Loren Burkholder 2022-04-19 23:18:11 -04:00
parent e7c24b094f
commit 169384f0fa
7 changed files with 98 additions and 69 deletions

View file

@ -348,58 +348,15 @@ Page {
height: avatar.height height: avatar.height
spacing: Nheko.paddingSmall spacing: Nheko.paddingSmall
RowLayout { Component {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
spacing: Nheko.paddingSmall
ElidedLabel {
id: rN
Layout.alignment: Qt.AlignBaseline
color: roomItem.importantText
elideWidth: width
fullText: roomName
textFormat: Text.RichText
Layout.fillWidth: true
}
Label {
id: timestamp
visible: !isInvite && !isSpace
width: visible ? 0 : undefined
Layout.alignment: Qt.AlignRight | Qt.AlignBaseline
font.pixelSize: fontMetrics.font.pixelSize * 0.9
color: roomItem.unimportantText
text: time
}
}
RowLayout {
Layout.fillWidth: true
spacing: 0
visible: !isSpace
height: visible ? 0 : undefined
Layout.alignment: Qt.AlignBottom
ElidedLabel {
color: roomItem.unimportantText
font.pixelSize: fontMetrics.font.pixelSize * 0.9
elideWidth: width
fullText: lastMessage
textFormat: Text.RichText
Layout.fillWidth: true
}
Rectangle {
id: notificationBubble id: notificationBubble
Rectangle {
visible: notificationCount > 0 visible: notificationCount > 0
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.leftMargin: Nheko.paddingSmall Layout.leftMargin: Nheko.paddingSmall
height: notificationBubbleText.height + Nheko.paddingMedium height: notificationBubbleText.height + Nheko.paddingMedium
Layout.preferredWidth: Math.max(notificationBubbleText.width, height) width: Math.max(notificationBubbleText.width, height)
radius: height / 2 radius: height / 2
color: hasLoudNotification ? Nheko.theme.red : roomItem.bubbleBackground color: hasLoudNotification ? Nheko.theme.red : roomItem.bubbleBackground
ToolTip.text: notificationCount ToolTip.text: notificationCount
@ -425,7 +382,66 @@ Page {
} }
} }
}
RowLayout {
id: titleRow
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
spacing: Nheko.paddingSmall
ElidedLabel {
id: rN
Layout.alignment: Qt.AlignBaseline
color: roomItem.importantText
elideWidth: width
fullText: roomName
textFormat: Text.RichText
Layout.fillWidth: true
}
Label {
id: timestamp
visible: !isInvite && !isSpace
width: visible ? 0 : undefined
Layout.alignment: Qt.AlignRight | Qt.AlignBaseline
font.pixelSize: fontMetrics.font.pixelSize * 0.9
color: roomItem.unimportantText
text: time
}
Loader {
sourceComponent: notificationBubble
active: isSpace
}
}
RowLayout {
id: subtextRow
Layout.fillWidth: true
spacing: 0
visible: !isSpace
height: visible ? 0 : undefined
Layout.alignment: Qt.AlignBottom
ElidedLabel {
color: roomItem.unimportantText
font.pixelSize: fontMetrics.font.pixelSize * 0.9
elideWidth: width
fullText: lastMessage
textFormat: Text.RichText
Layout.fillWidth: true
}
Loader {
sourceComponent: notificationBubble
active: !isSpace
}
} }
} }

View file

@ -27,6 +27,7 @@
#include <cmark.h> #include <cmark.h>
#include "Cache.h" #include "Cache.h"
#include "Cache_p.h"
#include "Config.h" #include "Config.h"
#include "EventAccessors.h" #include "EventAccessors.h"
#include "Logging.h" #include "Logging.h"
@ -880,3 +881,17 @@ utils::markRoomAsDirect(QString roomid, std::vector<RoomMember> members)
}); });
}); });
} }
int
utils::getChildNotificationsForSpace(const QString &spaceId)
{
auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(spaceId.toStdString()));
int total{0};
for (const auto &[childId, child] : children) {
if (child.is_space)
total += utils::getChildNotificationsForSpace(childId);
else
total += child.notification_count;
}
return total;
}

View file

@ -311,4 +311,7 @@ removeDirectFromRoom(QString roomid);
void void
markRoomAsDirect(QString roomid, std::vector<RoomMember> members); markRoomAsDirect(QString roomid, std::vector<RoomMember> members);
int
getChildNotificationsForSpace(const QString &spaceId);
} }

View file

@ -12,6 +12,7 @@
#include "ChatPage.h" #include "ChatPage.h"
#include "Logging.h" #include "Logging.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
#include "Utils.h"
CommunitiesModel::CommunitiesModel(QObject *parent) CommunitiesModel::CommunitiesModel(QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
@ -131,7 +132,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const
case CommunitiesModel::Roles::Id: case CommunitiesModel::Roles::Id:
return "space:" + id; return "space:" + id;
case CommunitiesModel::Roles::UnreadMessages: case CommunitiesModel::Roles::UnreadMessages:
return getChildNotifications(id); return utils::getChildNotificationsForSpace(id);
} }
} else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) {
auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); auto tag = tags_.at(index.row() - 2 - spaceOrder_.size());
@ -465,20 +466,6 @@ CommunitiesModel::toggleTagId(QString tagId)
emit hiddenTagsChanged(); emit hiddenTagsChanged();
} }
int
CommunitiesModel::getChildNotifications(const QString &space_id) const
{
auto children = cache::getRoomInfo(cache::client()->getChildRoomIds(space_id.toStdString()));
int total{0};
for (const auto &[child_id, child] : children) {
if (child.is_space)
total += getChildNotifications(child_id);
else
total += child.notification_count;
}
return total;
}
FilteredCommunitiesModel::FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent) FilteredCommunitiesModel::FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent)
: QSortFilterProxyModel(parent) : QSortFilterProxyModel(parent)
{ {

View file

@ -148,8 +148,6 @@ signals:
void containsSubspacesChanged(); void containsSubspacesChanged();
private: private:
int getChildNotifications(const QString &space_id) const;
QStringList tags_; QStringList tags_;
QString currentTagId_; QString currentTagId_;
QStringList hiddenTagIds_; QStringList hiddenTagIds_;

View file

@ -330,10 +330,13 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification)
Qt::DisplayRole, Qt::DisplayRole,
}); });
if (getRoomById(room_id)->isSpace())
return; // no need to update space notifications
int total_unread_msgs = 0; int total_unread_msgs = 0;
for (const auto &room : qAsConst(models)) { for (const auto &room : qAsConst(models)) {
if (!room.isNull()) if (!room.isNull() && !room->isSpace())
total_unread_msgs += room->notificationCount(); total_unread_msgs += room->notificationCount();
} }

View file

@ -354,7 +354,8 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
auto roomInfo = cache::singleRoomInfo(room_id_.toStdString()); auto roomInfo = cache::singleRoomInfo(room_id_.toStdString());
this->isSpace_ = roomInfo.is_space; this->isSpace_ = roomInfo.is_space;
this->notification_count = roomInfo.notification_count; this->notification_count =
isSpace_ ? utils::getChildNotificationsForSpace(room_id_) : roomInfo.notification_count;
this->highlight_count = roomInfo.highlight_count; this->highlight_count = roomInfo.highlight_count;
lastMessage_.timestamp = roomInfo.approximate_last_modification_ts; lastMessage_.timestamp = roomInfo.approximate_last_modification_ts;
@ -362,6 +363,12 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
// needs to be // needs to be
connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged); connect(this, &TimelineModel::roomNameChanged, this, &TimelineModel::plainRoomNameChanged);
if (isSpace_)
connect(ChatPage::instance(), &ChatPage::unreadMessages, this, [this](int) {
notification_count = utils::getChildNotificationsForSpace(room_id_);
emit notificationsChanged();
});
connect( connect(
this, this,
&TimelineModel::redactionFailed, &TimelineModel::redactionFailed,