mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Add initial support for unread message count
- Add border width on Badge
This commit is contained in:
parent
793c2136b7
commit
3b0ff1a4cd
11 changed files with 102 additions and 11 deletions
|
@ -54,7 +54,7 @@ public:
|
||||||
~HistoryView();
|
~HistoryView();
|
||||||
|
|
||||||
void addHistoryItem(const Event &event, const QString &color, bool with_sender);
|
void addHistoryItem(const Event &event, const QString &color, bool with_sender);
|
||||||
void addEvents(const QList<Event> &events);
|
int addEvents(const QList<Event> &events);
|
||||||
void addUserTextMessage(const QString &msg, int txn_id);
|
void addUserTextMessage(const QString &msg, int txn_id);
|
||||||
void updatePendingMessage(int txn_id, QString event_id);
|
void updatePendingMessage(int txn_id, QString event_id);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -44,6 +44,9 @@ public:
|
||||||
static QString getUserColor(const QString &userid);
|
static QString getUserColor(const QString &userid);
|
||||||
static QMap<QString, QString> NICK_COLORS;
|
static QMap<QString, QString> NICK_COLORS;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void unreadMessages(QString roomid, int count);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setHistoryView(const RoomInfo &info);
|
void setHistoryView(const RoomInfo &info);
|
||||||
void sendTextMessage(const QString &msg);
|
void sendTextMessage(const QString &msg);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <QtWidgets/QWidget>
|
#include <QtWidgets/QWidget>
|
||||||
|
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
|
#include "Badge.h"
|
||||||
#include "RippleOverlay.h"
|
#include "RippleOverlay.h"
|
||||||
#include "RoomInfo.h"
|
#include "RoomInfo.h"
|
||||||
|
|
||||||
|
@ -35,6 +36,9 @@ public:
|
||||||
RoomInfoListItem(RoomInfo info, QWidget *parent = 0);
|
RoomInfoListItem(RoomInfo info, QWidget *parent = 0);
|
||||||
~RoomInfoListItem();
|
~RoomInfoListItem();
|
||||||
|
|
||||||
|
void updateUnreadMessageCount(int count);
|
||||||
|
void clearUnreadMessageCount();
|
||||||
|
|
||||||
inline bool isPressed();
|
inline bool isPressed();
|
||||||
inline RoomInfo info();
|
inline RoomInfo info();
|
||||||
inline void setAvatar(const QImage &avatar_image);
|
inline void setAvatar(const QImage &avatar_image);
|
||||||
|
@ -67,12 +71,15 @@ private:
|
||||||
QLabel *roomTopic_;
|
QLabel *roomTopic_;
|
||||||
|
|
||||||
Avatar *roomAvatar_;
|
Avatar *roomAvatar_;
|
||||||
|
Badge *unreadMessagesBadge_;
|
||||||
|
|
||||||
QString pressed_style_;
|
QString pressed_style_;
|
||||||
QString normal_style_;
|
QString normal_style_;
|
||||||
|
|
||||||
bool is_pressed_;
|
bool is_pressed_;
|
||||||
|
|
||||||
int max_height_;
|
int max_height_;
|
||||||
|
int unread_msg_count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool RoomInfoListItem::isPressed()
|
inline bool RoomInfoListItem::isPressed()
|
||||||
|
|
|
@ -52,6 +52,7 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void updateRoomAvatar(const QString &roomid, const QPixmap &img);
|
void updateRoomAvatar(const QString &roomid, const QPixmap &img);
|
||||||
void highlightSelectedRoom(const RoomInfo &info);
|
void highlightSelectedRoom(const RoomInfo &info);
|
||||||
|
void updateUnreadMessageCount(const QString &roomid, int count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::RoomList *ui;
|
Ui::RoomList *ui;
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
void setRelativeXPosition(qreal x);
|
void setRelativeXPosition(qreal x);
|
||||||
void setRelativeYPosition(qreal y);
|
void setRelativeYPosition(qreal y);
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
|
void setDiameter(int diameter);
|
||||||
|
|
||||||
QIcon icon() const;
|
QIcon icon() const;
|
||||||
QString text() const;
|
QString text() const;
|
||||||
|
@ -40,9 +41,10 @@ public:
|
||||||
qreal relativeXPosition() const;
|
qreal relativeXPosition() const;
|
||||||
qreal relativeYPosition() const;
|
qreal relativeYPosition() const;
|
||||||
|
|
||||||
|
int diameter() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
int getDiameter() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
@ -55,6 +57,7 @@ private:
|
||||||
QString text_;
|
QString text_;
|
||||||
|
|
||||||
int padding_;
|
int padding_;
|
||||||
|
int diameter_;
|
||||||
|
|
||||||
qreal x_;
|
qreal x_;
|
||||||
qreal y_;
|
qreal y_;
|
||||||
|
|
|
@ -64,6 +64,11 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
|
||||||
view_manager_,
|
view_manager_,
|
||||||
SLOT(setHistoryView(const RoomInfo &)));
|
SLOT(setHistoryView(const RoomInfo &)));
|
||||||
|
|
||||||
|
connect(view_manager_,
|
||||||
|
SIGNAL(unreadMessages(const QString &, int)),
|
||||||
|
room_list_,
|
||||||
|
SLOT(updateUnreadMessageCount(const QString &, int)));
|
||||||
|
|
||||||
connect(text_input_,
|
connect(text_input_,
|
||||||
SIGNAL(sendTextMessage(const QString &)),
|
SIGNAL(sendTextMessage(const QString &)),
|
||||||
view_manager_,
|
view_manager_,
|
||||||
|
|
|
@ -50,11 +50,13 @@ void HistoryView::sliderRangeChanged(int min, int max)
|
||||||
scroll_area_->verticalScrollBar()->setValue(max);
|
scroll_area_->verticalScrollBar()->setValue(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryView::addEvents(const QList<Event> &events)
|
int HistoryView::addEvents(const QList<Event> &events)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
auto local_user = settings.value("auth/user_id").toString();
|
auto local_user = settings.value("auth/user_id").toString();
|
||||||
|
|
||||||
|
int message_count = 0;
|
||||||
|
|
||||||
for (const auto &event : events) {
|
for (const auto &event : events) {
|
||||||
if (event.type() == "m.room.message") {
|
if (event.type() == "m.room.message") {
|
||||||
auto msg_type = event.content().value("msgtype").toString();
|
auto msg_type = event.content().value("msgtype").toString();
|
||||||
|
@ -70,9 +72,13 @@ void HistoryView::addEvents(const QList<Event> &events)
|
||||||
|
|
||||||
addHistoryItem(event, color, with_sender);
|
addHistoryItem(event, color, with_sender);
|
||||||
last_sender_ = event.sender();
|
last_sender_ = event.sender();
|
||||||
|
|
||||||
|
message_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return message_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryView::init()
|
void HistoryView::init()
|
||||||
|
|
|
@ -106,7 +106,11 @@ void HistoryViewManager::sync(const Rooms &rooms)
|
||||||
auto view = views_.value(roomid);
|
auto view = views_.value(roomid);
|
||||||
auto events = it.value().timeline().events();
|
auto events = it.value().timeline().events();
|
||||||
|
|
||||||
view->addEvents(events);
|
int msgs_added = view->addEvents(events);
|
||||||
|
|
||||||
|
// TODO: Take into account window focus
|
||||||
|
if (msgs_added > 0 && roomid != active_room_.id())
|
||||||
|
emit unreadMessages(roomid, msgs_added);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ RoomInfoListItem::RoomInfoListItem(RoomInfo info, QWidget *parent)
|
||||||
, info_(info)
|
, info_(info)
|
||||||
, is_pressed_(false)
|
, is_pressed_(false)
|
||||||
, max_height_(60)
|
, max_height_(60)
|
||||||
|
, unread_msg_count_(0)
|
||||||
{
|
{
|
||||||
normal_style_ =
|
normal_style_ =
|
||||||
"QWidget { color: black; background-color: #f8fbfe}"
|
"QWidget { color: black; background-color: #f8fbfe}"
|
||||||
|
@ -63,6 +64,16 @@ RoomInfoListItem::RoomInfoListItem(RoomInfo info, QWidget *parent)
|
||||||
roomAvatar_->setSize(max_height_ - 20);
|
roomAvatar_->setSize(max_height_ - 20);
|
||||||
roomAvatar_->setTextColor("#555459");
|
roomAvatar_->setTextColor("#555459");
|
||||||
roomAvatar_->setBackgroundColor("#d6dde3");
|
roomAvatar_->setBackgroundColor("#d6dde3");
|
||||||
|
|
||||||
|
unreadMessagesBadge_ = new Badge(roomAvatar_);
|
||||||
|
unreadMessagesBadge_->setRelativePosition(12, 10);
|
||||||
|
unreadMessagesBadge_->setDiameter(5);
|
||||||
|
unreadMessagesBadge_->setBackgroundColor("#f8fbfe");
|
||||||
|
unreadMessagesBadge_->setTextColor("black");
|
||||||
|
|
||||||
|
// TODO: Initialize when nheko can restore messages from previous session.
|
||||||
|
unreadMessagesBadge_->hide();
|
||||||
|
|
||||||
avatarLayout_->addWidget(roomAvatar_);
|
avatarLayout_->addWidget(roomAvatar_);
|
||||||
|
|
||||||
roomName_ = new QLabel(info_.name(), textWidget_);
|
roomName_ = new QLabel(info_.name(), textWidget_);
|
||||||
|
@ -94,6 +105,20 @@ RoomInfoListItem::RoomInfoListItem(RoomInfo info, QWidget *parent)
|
||||||
setLayout(topLayout_);
|
setLayout(topLayout_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RoomInfoListItem::updateUnreadMessageCount(int count)
|
||||||
|
{
|
||||||
|
unread_msg_count_ += count;
|
||||||
|
unreadMessagesBadge_->setText(QString::number(unread_msg_count_));
|
||||||
|
unreadMessagesBadge_->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomInfoListItem::clearUnreadMessageCount()
|
||||||
|
{
|
||||||
|
unread_msg_count_ = 0;
|
||||||
|
unreadMessagesBadge_->setText("");
|
||||||
|
unreadMessagesBadge_->hide();
|
||||||
|
}
|
||||||
|
|
||||||
void RoomInfoListItem::setPressedState(bool state)
|
void RoomInfoListItem::setPressedState(bool state)
|
||||||
{
|
{
|
||||||
if (!is_pressed_ && state) {
|
if (!is_pressed_ && state) {
|
||||||
|
|
|
@ -81,6 +81,16 @@ RoomInfo RoomList::extractRoomInfo(const State &room_state)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RoomList::updateUnreadMessageCount(const QString &roomid, int count)
|
||||||
|
{
|
||||||
|
if (!rooms_.contains(roomid)) {
|
||||||
|
qWarning() << "UpdateUnreadMessageCount: Unknown roomid";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rooms_[roomid]->updateUnreadMessageCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
void RoomList::setInitialRooms(const Rooms &rooms)
|
void RoomList::setInitialRooms(const Rooms &rooms)
|
||||||
{
|
{
|
||||||
rooms_.clear();
|
rooms_.clear();
|
||||||
|
@ -117,6 +127,16 @@ void RoomList::highlightSelectedRoom(const RoomInfo &info)
|
||||||
{
|
{
|
||||||
emit roomChanged(info);
|
emit roomChanged(info);
|
||||||
|
|
||||||
|
if (!rooms_.contains(info.id())) {
|
||||||
|
qDebug() << "RoomList: clicked unknown roomid";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Send a read receipt for the last event.
|
||||||
|
auto room = rooms_[info.id()];
|
||||||
|
room->clearUnreadMessageCount();
|
||||||
|
|
||||||
for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) {
|
for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) {
|
||||||
if (it.key() != info.id())
|
if (it.key() != info.id())
|
||||||
it.value()->setPressedState(false);
|
it.value()->setPressedState(false);
|
||||||
|
|
|
@ -30,12 +30,14 @@ void Badge::init()
|
||||||
{
|
{
|
||||||
x_ = 0;
|
x_ = 0;
|
||||||
y_ = 0;
|
y_ = 0;
|
||||||
padding_ = 10;
|
// TODO: Make padding configurable.
|
||||||
|
padding_ = 5;
|
||||||
|
diameter_ = 24;
|
||||||
|
|
||||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
QFont _font(font());
|
QFont _font(font());
|
||||||
_font.setPointSizeF(10);
|
_font.setPointSizeF(7.5);
|
||||||
_font.setStyleName("Bold");
|
_font.setStyleName("Bold");
|
||||||
|
|
||||||
setFont(_font);
|
setFont(_font);
|
||||||
|
@ -54,7 +56,7 @@ QIcon Badge::icon() const
|
||||||
|
|
||||||
QSize Badge::sizeHint() const
|
QSize Badge::sizeHint() const
|
||||||
{
|
{
|
||||||
const int d = getDiameter();
|
const int d = diameter();
|
||||||
return QSize(d + 4, d + 4);
|
return QSize(d + 4, d + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +143,14 @@ void Badge::setText(const QString &text)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Badge::setDiameter(int diameter)
|
||||||
|
{
|
||||||
|
if (diameter > 0) {
|
||||||
|
diameter_ = diameter;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Badge::paintEvent(QPaintEvent *)
|
void Badge::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
@ -154,13 +164,20 @@ void Badge::paintEvent(QPaintEvent *)
|
||||||
painter.setBrush(brush);
|
painter.setBrush(brush);
|
||||||
painter.setPen(Qt::NoPen);
|
painter.setPen(Qt::NoPen);
|
||||||
|
|
||||||
const int d = getDiameter();
|
const int d = diameter();
|
||||||
|
|
||||||
QRectF r(0, 0, d, d);
|
QRectF r(0, 0, d, d);
|
||||||
r.translate(QPointF((width() - d), (height() - d)) / 2);
|
r.translate(QPointF((width() - d), (height() - d)) / 2);
|
||||||
|
|
||||||
if (icon_.isNull()) {
|
if (icon_.isNull()) {
|
||||||
|
QPen pen;
|
||||||
|
// TODO: Make badge width configurable.
|
||||||
|
pen.setWidth(1);
|
||||||
|
pen.setColor(textColor());
|
||||||
|
|
||||||
|
painter.setPen(pen);
|
||||||
painter.drawEllipse(r);
|
painter.drawEllipse(r);
|
||||||
|
|
||||||
painter.setPen(textColor());
|
painter.setPen(textColor());
|
||||||
painter.setBrush(Qt::NoBrush);
|
painter.setBrush(Qt::NoBrush);
|
||||||
painter.drawText(r.translated(0, -0.5), Qt::AlignCenter, text_);
|
painter.drawText(r.translated(0, -0.5), Qt::AlignCenter, text_);
|
||||||
|
@ -176,11 +193,11 @@ void Badge::paintEvent(QPaintEvent *)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Badge::getDiameter() const
|
int Badge::diameter() const
|
||||||
{
|
{
|
||||||
if (icon_.isNull()) {
|
if (icon_.isNull()) {
|
||||||
return qMax(size_.width(), size_.height()) + padding_;
|
return qMax(size_.width(), size_.height()) + padding_;
|
||||||
}
|
}
|
||||||
// FIXME: Move this to Theme.h as the default
|
|
||||||
return 24;
|
return diameter_;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue