Bring unread mention/reactions to chat list

This commit is contained in:
Sebastian Wolf 2022-06-06 15:55:21 +02:00
parent 9ff7a8371d
commit 99910a3f3a
No known key found for this signature in database
GPG key ID: CEA9522B5F38A90A
9 changed files with 143 additions and 2 deletions

View file

@ -24,6 +24,8 @@ PhotoTextsListItem {
// message date
tertiaryText.text: showDraft ? Functions.getDateTimeElapsed(draft_message_date) : ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
unreadCount: unread_count
unreadReactionCount: unread_reaction_count
unreadMentionCount: unread_mention_count
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
isMarkedAsUnread: is_marked_as_unread
isPinned: is_pinned
@ -48,7 +50,7 @@ PhotoTextsListItem {
sourceComponent: Component {
ContextMenu {
MenuItem {
visible: unread_count > 0
visible: unread_count > 0 || unread_reaction_count > 0 || unread_mention_count > 0
onClicked: {
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
tdLibWrapper.readAllChatMentions(chat_id);
@ -59,7 +61,7 @@ PhotoTextsListItem {
}
MenuItem {
visible: unread_count === 0
visible: unread_count === 0 && unread_reaction_count === 0 && unread_mention_count === 0
onClicked: {
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, !is_marked_as_unread);
}

View file

@ -11,6 +11,8 @@ ListItem {
property alias tertiaryText: tertiaryText //usually last message date
property int unreadCount: 0
property int unreadMentionCount: 0
property int unreadReactionCount: 0
property bool isSecret: false
property bool isVerified: false
property bool isMarkedAsUnread: false
@ -103,6 +105,50 @@ ListItem {
opacity: isMuted ? Theme.opacityHigh : 1.0
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
}
Rectangle {
id: chatUnreadReactionCountBackground
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
anchors.right: parent.right
anchors.top: parent.top
radius: parent.width / 2
visible: chatListViewItem.unreadReactionCount > 0
}
Text {
id: chatUnreadReactionCount
font.pixelSize: Theme.fontSizeSmall
font.bold: true
color: Theme.primaryColor
anchors.centerIn: chatUnreadReactionCountBackground
visible: chatListViewItem.unreadReactionCount > 0
opacity: isMuted ? Theme.opacityHigh : 1.0
text: "❤️"
}
Rectangle {
id: chatUnreadMentionCountBackground
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
anchors.right: parent.right
anchors.top: parent.top
radius: parent.width / 2
visible: chatListViewItem.unreadMentionCount > 0
}
Text {
id: chatUnreadMentionCount
font.pixelSize: Theme.fontSizeSmall
font.bold: true
color: Theme.primaryColor
anchors.centerIn: chatUnreadMentionCountBackground
visible: chatListViewItem.unreadMentionCount > 0
opacity: isMuted ? Theme.opacityHigh : 1.0
text: "@"
}
}
}
Column {

View file

@ -1191,6 +1191,7 @@ Page {
}
} else {
tdLibWrapper.readAllChatMentions(chatInformation.id);
tdLibWrapper.readAllChatReactions(chatInformation.id);
}
manuallyScrolledToBottom = chatView.atYEnd
}

View file

@ -42,6 +42,8 @@ namespace {
const QString BASIC_GROUP_ID("basic_group_id");
const QString SUPERGROUP_ID("supergroup_id");
const QString UNREAD_COUNT("unread_count");
const QString UNREAD_MENTION_COUNT("unread_mention_count");
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
const QString NOTIFICATION_SETTINGS("notification_settings");
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
@ -66,6 +68,8 @@ public:
const QVariant lastMessage(const QString &key) const;
QString title() const;
int unreadCount() const;
int unreadMentionCount() const;
int unreadReactionCount() const;
QVariant photoSmall() const;
qlonglong lastReadInboxMessageId() const;
qlonglong senderUserId() const;
@ -159,6 +163,16 @@ int ChatListModel::ChatData::unreadCount() const
return chatData.value(UNREAD_COUNT).toInt();
}
int ChatListModel::ChatData::unreadMentionCount() const
{
return chatData.value(UNREAD_MENTION_COUNT).toInt();
}
int ChatListModel::ChatData::unreadReactionCount() const
{
return chatData.value(UNREAD_REACTION_COUNT).toInt();
}
QVariant ChatListModel::ChatData::photoSmall() const
{
return chatData.value(PHOTO).toMap().value(SMALL);
@ -384,6 +398,8 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper, AppSettings *appSetting
connect(tdLibWrapper, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SLOT(handleChatIsMarkedAsUnreadUpdated(qlonglong, bool)));
connect(tdLibWrapper, SIGNAL(chatPinnedUpdated(qlonglong, bool)), this, SLOT(handleChatPinnedUpdated(qlonglong, bool)));
connect(tdLibWrapper, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SLOT(handleChatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
connect(tdLibWrapper, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadMentionCountUpdated(qlonglong, int)));
connect(tdLibWrapper, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadReactionCountUpdated(qlonglong, int)));
// Don't start the timer until we have at least one chat
relativeTimeRefreshTimer = new QTimer(this);
@ -418,6 +434,8 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
roles.insert(ChatListModel::RoleTitle, "title");
roles.insert(ChatListModel::RolePhotoSmall, "photo_small");
roles.insert(ChatListModel::RoleUnreadCount, "unread_count");
roles.insert(ChatListModel::RoleUnreadMentionCount, "unread_mention_count");
roles.insert(ChatListModel::RoleUnreadReactionCount, "unread_reaction_count");
roles.insert(ChatListModel::RoleLastReadInboxMessageId, "last_read_inbox_message_id");
roles.insert(ChatListModel::RoleLastMessageSenderId, "last_message_sender_id");
roles.insert(ChatListModel::RoleLastMessageDate, "last_message_date");
@ -453,6 +471,8 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
case ChatListModel::RoleTitle: return data->title();
case ChatListModel::RolePhotoSmall: return data->photoSmall();
case ChatListModel::RoleUnreadCount: return data->unreadCount();
case ChatListModel::RoleUnreadMentionCount: return data->unreadMentionCount();
case ChatListModel::RoleUnreadReactionCount: return data->unreadReactionCount();
case ChatListModel::RoleLastReadInboxMessageId: return data->lastReadInboxMessageId();
case ChatListModel::RoleLastMessageSenderId: return data->senderUserId();
case ChatListModel::RoleLastMessageText: return data->senderMessageText();
@ -969,6 +989,46 @@ void ChatListModel::handleChatDraftMessageUpdated(qlonglong chatId, const QVaria
}
}
void ChatListModel::handleChatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount)
{
if (chatIndexMap.contains(chatId)) {
LOG("Updating mention count for" << chatId << unreadMentionCount);
const int chatIndex = chatIndexMap.value(chatId);
ChatData *chat = chatList.at(chatIndex);
chat->chatData.insert(UNREAD_MENTION_COUNT, unreadMentionCount);
QVector<int> changedRoles;
changedRoles.append(ChatListModel::RoleUnreadMentionCount);
const QModelIndex modelIndex(index(chatIndex));
emit dataChanged(modelIndex, modelIndex, changedRoles);
} else {
ChatData *chat = hiddenChats.value(chatId);
if (chat) {
LOG("Updating mention count for hidden chat" << chatId << unreadMentionCount);
chat->chatData.insert(UNREAD_MENTION_COUNT, unreadMentionCount);
}
}
}
void ChatListModel::handleChatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount)
{
if (chatIndexMap.contains(chatId)) {
LOG("Updating reaction count for" << chatId << unreadReactionCount);
const int chatIndex = chatIndexMap.value(chatId);
ChatData *chat = chatList.at(chatIndex);
chat->chatData.insert(UNREAD_REACTION_COUNT, unreadReactionCount);
QVector<int> changedRoles;
changedRoles.append(ChatListModel::RoleUnreadReactionCount);
const QModelIndex modelIndex(index(chatIndex));
emit dataChanged(modelIndex, modelIndex, changedRoles);
} else {
ChatData *chat = hiddenChats.value(chatId);
if (chat) {
LOG("Updating reaction count for hidden chat" << chatId << unreadReactionCount);
chat->chatData.insert(UNREAD_REACTION_COUNT, unreadReactionCount);
}
}
}
void ChatListModel::handleRelativeTimeRefreshTimer()
{
LOG("Refreshing timestamps");

View file

@ -40,6 +40,8 @@ public:
RoleTitle,
RolePhotoSmall,
RoleUnreadCount,
RoleUnreadMentionCount,
RoleUnreadReactionCount,
RoleLastReadInboxMessageId,
RoleLastMessageSenderId,
RoleLastMessageDate,
@ -89,6 +91,8 @@ private slots:
void handleChatPinnedUpdated(qlonglong chatId, bool chatIsPinned);
void handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
void handleChatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
void handleChatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
void handleChatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
void handleRelativeTimeRefreshTimer();
signals:

View file

@ -44,6 +44,8 @@ namespace {
const QString LAST_MESSAGE("last_message");
const QString TOTAL_COUNT("total_count");
const QString UNREAD_COUNT("unread_count");
const QString UNREAD_MENTION_COUNT("unread_mention_count");
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
const QString TEXT("text");
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
@ -163,6 +165,8 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("updateMessageInteractionInfo", &TDLibReceiver::processUpdateMessageInteractionInfo);
handlers.insert("sessions", &TDLibReceiver::processSessions);
handlers.insert("availableReactions", &TDLibReceiver::processAvailableReactions);
handlers.insert("updateChatUnreadMentionCount", &TDLibReceiver::processUpdateChatUnreadMentionCount);
handlers.insert("updateChatUnreadReactionCount", &TDLibReceiver::processUpdateChatUnreadReactionCount);
}
void TDLibReceiver::setActive(bool active)
@ -698,6 +702,22 @@ void TDLibReceiver::processAvailableReactions(const QVariantMap &receivedInforma
}
}
void TDLibReceiver::processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation)
{
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
const int unreadMentionCount = receivedInformation.value(UNREAD_MENTION_COUNT).toInt();
LOG("Chat unread mention count updated" << chatId << unreadMentionCount);
emit chatUnreadMentionCountUpdated(chatId, unreadMentionCount);
}
void TDLibReceiver::processUpdateChatUnreadReactionCount(const QVariantMap &receivedInformation)
{
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
const int unreadReactionCount = receivedInformation.value(UNREAD_REACTION_COUNT).toInt();
LOG("Chat unread reaction count updated" << chatId << unreadReactionCount);
emit chatUnreadReactionCountUpdated(chatId, unreadReactionCount);
}
// Recursively removes (some) unused entries from QVariantMaps to reduce
// memory usage. QStrings allocated by QVariantMaps are the top consumers
// of memory. The biggest saving is achieved by removing "outline" from

View file

@ -103,6 +103,8 @@ signals:
void okReceived(const QString &request);
void sessionsReceived(const QVariantList &sessions);
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
void chatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
private:
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
@ -182,6 +184,8 @@ private:
void processUpdateMessageInteractionInfo(const QVariantMap &receivedInformation);
void processSessions(const QVariantMap &receivedInformation);
void processAvailableReactions(const QVariantMap &receivedInformation);
void processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation);
void processUpdateChatUnreadReactionCount(const QVariantMap &receivedInformation);
};
#endif // TDLIBRECEIVER_H

View file

@ -166,6 +166,8 @@ void TDLibWrapper::initializeTDLibReceiver() {
connect(this->tdLibReceiver, SIGNAL(okReceived(QString)), this, SIGNAL(okReceived(QString)));
connect(this->tdLibReceiver, SIGNAL(sessionsReceived(QVariantList)), this, SIGNAL(sessionsReceived(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(availableReactionsReceived(qlonglong, QStringList)), this, SIGNAL(availableReactionsReceived(qlonglong, QStringList)));
connect(this->tdLibReceiver, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)));
connect(this->tdLibReceiver, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)));
this->tdLibReceiver->start();
}

View file

@ -322,6 +322,8 @@ signals:
void sessionsReceived(const QVariantList &sessions);
void openFileExternally(const QString &filePath);
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
void chatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
void tgUrlFound(const QString &tgUrl);
public slots: