|
|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
#include <QCoreApplication> |
|
|
|
|
#include "memberlistmodel.h" |
|
|
|
|
#include "avatars/avatarmanager.h" |
|
|
|
|
#include "../transport/gui_bridge.h" |
|
|
|
|
#include <QPainter> |
|
|
|
|
#include <QFont> |
|
|
|
|
@ -12,12 +13,28 @@ extern "C" {
|
|
|
|
|
#include "../../../lib/mem.h" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define CHAT_MEMBER_DISPLAY_SIZE 79 |
|
|
|
|
static void applyPhoto(MemberListItem& item, const QString& channel) { |
|
|
|
|
auto* manager = AvatarManager::instance(); if (!manager) return; |
|
|
|
|
const QImage image = manager->image(channel, item.nodeId); if (image.isNull()) return; |
|
|
|
|
QPixmap pixmap(24, 24); pixmap.fill(Qt::transparent); |
|
|
|
|
QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); |
|
|
|
|
QPainterPath clip; clip.addEllipse(QRectF(0, 0, 24, 24)); painter.setClipPath(clip); |
|
|
|
|
painter.drawImage(QRect(0, 0, 24, 24), image); painter.setClipping(false); |
|
|
|
|
painter.setPen(QPen(Qt::white, 1)); painter.setBrush(item.online ? QColor("#4CAF50") : QColor("#9E9E9E")); |
|
|
|
|
painter.drawEllipse(QRect(17, 17, 6, 6)); painter.end(); item.avatar = pixmap; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MemberListModel::MemberListModel(QObject* parent) |
|
|
|
|
: QAbstractListModel(parent) |
|
|
|
|
, m_rttTimer(new QTimer(this)) |
|
|
|
|
{ |
|
|
|
|
if (auto* manager = AvatarManager::instance()) connect(manager, &AvatarManager::changed, this, |
|
|
|
|
[this](const QString& channel, quint64 owner) { |
|
|
|
|
if (channel != m_channelId) return; |
|
|
|
|
for (auto it = m_cache.begin(); it != m_cache.end(); ++it) if (it->nodeId == owner) { |
|
|
|
|
applyPhoto(*it, channel); emit dataChanged(index(it.key()), index(it.key()), {Qt::DecorationRole}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
m_rttTimer->setInterval(2000); |
|
|
|
|
connect(m_rttTimer, &QTimer::timeout, this, &MemberListModel::refreshRtt); |
|
|
|
|
m_rttTimer->start(); |
|
|
|
|
@ -133,8 +150,8 @@ static void deserialize_member(const uint8_t* src, MemberListItem& item) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MemberListModel::onMemberList(const QString& chId, int count, const uint8_t* data, int dataLen) { |
|
|
|
|
(void)dataLen; |
|
|
|
|
if (chId != m_channelId) return; |
|
|
|
|
if (count < 0 || count > dataLen / CHAT_MEMBER_DISPLAY_SIZE) return; |
|
|
|
|
|
|
|
|
|
beginResetModel(); |
|
|
|
|
m_totalCount = 0; |
|
|
|
|
@ -144,6 +161,7 @@ void MemberListModel::onMemberList(const QString& chId, int count, const uint8_t
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
|
MemberListItem item; |
|
|
|
|
deserialize_member(data + i * CHAT_MEMBER_DISPLAY_SIZE, item); |
|
|
|
|
applyPhoto(item, chId); |
|
|
|
|
if ((item.flags & CHAT_MEMBER_FLAG_DELETED) && !m_isOwner) continue; |
|
|
|
|
m_cache[row++] = item; |
|
|
|
|
} |
|
|
|
|
@ -156,6 +174,7 @@ void MemberListModel::onMemberUpdated(const QString& chId, const uint8_t* data)
|
|
|
|
|
|
|
|
|
|
MemberListItem item; |
|
|
|
|
deserialize_member(data, item); |
|
|
|
|
applyPhoto(item, chId); |
|
|
|
|
|
|
|
|
|
/* find existing row by nodeId */ |
|
|
|
|
int row = -1; |
|
|
|
|
|