From 56bc1135a79400f4832aafb4632316c6dc1f19a6 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 4 Oct 2020 04:27:49 +0300 Subject: [PATCH] Don't show irrelevant groups by default chatListModel.showAllChats property can be used to switch visibility of irrelevant groups on and off. --- src/chatlistmodel.cpp | 368 +++++++++++++++++++++++++++++++++--------- src/chatlistmodel.h | 18 ++- src/tdlibreceiver.cpp | 12 +- src/tdlibreceiver.h | 4 +- src/tdlibwrapper.cpp | 156 ++++++++++++------ src/tdlibwrapper.h | 62 +++++-- 6 files changed, 470 insertions(+), 150 deletions(-) diff --git a/src/chatlistmodel.cpp b/src/chatlistmodel.cpp index 16d783d..a8ab31a 100644 --- a/src/chatlistmodel.cpp +++ b/src/chatlistmodel.cpp @@ -27,6 +27,7 @@ namespace { const QString ID("id"); const QString DATE("date"); const QString TEXT("text"); + const QString TYPE("type"); const QString TITLE("title"); const QString PHOTO("photo"); const QString SMALL("small"); @@ -35,6 +36,8 @@ namespace { const QString CONTENT("content"); const QString LAST_MESSAGE("last_message"); const QString SENDER_USER_ID("sender_user_id"); + const QString BASIC_GROUP_ID("basic_group_id"); + const QString SUPERGROUP_ID("supergroup_id"); const QString UNREAD_COUNT("unread_count"); const QString NOTIFICATION_SETTINGS("notification_settings"); const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id"); @@ -42,8 +45,12 @@ namespace { const QString TYPE_MAP("type"); const QString IS_CHANNEL("is_channel"); - const QString TYPE("@type"); + const QString _TYPE("@type"); const QString TYPE_MESSAGE_TEXT("messageText"); + const QString TYPE_CHAT_TYPE_PRIVATE("chatTypePrivate"); + const QString TYPE_CHAT_TYPE_BASIC_GROUP("chatTypeBasicGroup"); + const QString TYPE_CHAT_TYPE_SUPERGROUP("chatTypeSupergroup"); + const QString TYPE_CHAT_TYPE_SECRET("chatTypeSecret"); } class ChatListModel::ChatData @@ -52,6 +59,7 @@ public: enum Role { RoleDisplay = Qt::DisplayRole, RoleChatId, + RoleChatType, RoleTitle, RolePhotoSmall, RoleUnreadCount, @@ -59,6 +67,7 @@ public: RoleLastMessageSenderId, RoleLastMessageDate, RoleLastMessageText, + RoleChatMemberStatus, RoleIsChannel }; @@ -75,29 +84,50 @@ public: qlonglong senderMessageDate() const; QString senderMessageText() const; bool isChannel() const; + bool isHidden() const; bool updateUnreadCount(int unreadCount); bool updateLastReadInboxMessageId(qlonglong messageId); QVector updateLastMessage(const QVariantMap &message); + QVector updateGroup(const TDLibWrapper::Group *group); + static TDLibWrapper::ChatType chatTypeFromString(const QString &type); public: QVariantMap chatData; - QString chatId; + qlonglong chatId; qlonglong order; + qlonglong groupId; + TDLibWrapper::ChatType chatType; + TDLibWrapper::ChatMemberStatus memberStatus; QVariantMap userInformation; }; -ChatListModel::ChatData::ChatData(const QVariantMap &data, const QVariantMap &userInformation) : +ChatListModel::ChatData::ChatData(const QVariantMap &data, const QVariantMap &userInfo) : chatData(data), - chatId(data.value(ID).toString()), - order(data.value(ORDER).toLongLong()) + chatId(data.value(ID).toLongLong()), + order(data.value(ORDER).toLongLong()), + groupId(0), + memberStatus(TDLibWrapper::ChatMemberStatusUnknown), + userInformation(userInfo) { - this->userInformation = userInformation; + const QVariantMap type(data.value(TYPE).toMap()); + switch (chatType = chatTypeFromString(type.value(_TYPE).toString())) { + case TDLibWrapper::ChatTypeBasicGroup: + groupId = type.value(BASIC_GROUP_ID).toLongLong(); + break; + case TDLibWrapper::ChatTypeSupergroup: + groupId = type.value(SUPERGROUP_ID).toLongLong(); + break; + case TDLibWrapper::ChatTypeUnknown: + case TDLibWrapper::ChatTypePrivate: + case TDLibWrapper::ChatTypeSecret: + break; + } } int ChatListModel::ChatData::compareTo(const ChatData *other) const { if (order == other->order) { - return chatId.compare(other->chatId); + return (chatId < other->chatId) ? 1 : -1; } else { // This puts most recent ones to the top of the list return (order < other->order) ? 1 : -1; @@ -159,6 +189,32 @@ bool ChatListModel::ChatData::isChannel() const return chatData.value(TYPE_MAP).toMap().value(IS_CHANNEL).toBool(); } +bool ChatListModel::ChatData::isHidden() const +{ + // Cover all enum values so that compiler warns us when/if enum gets extended + switch (chatType) { + case TDLibWrapper::ChatTypeBasicGroup: + case TDLibWrapper::ChatTypeSupergroup: + switch (memberStatus) { + case TDLibWrapper::ChatMemberStatusLeft: + case TDLibWrapper::ChatMemberStatusUnknown: + return true; + case TDLibWrapper::ChatMemberStatusCreator: + case TDLibWrapper::ChatMemberStatusAdministrator: + case TDLibWrapper::ChatMemberStatusMember: + case TDLibWrapper::ChatMemberStatusRestricted: + case TDLibWrapper::ChatMemberStatusBanned: + break; + } + break; + case TDLibWrapper::ChatTypeUnknown: + case TDLibWrapper::ChatTypePrivate: + case TDLibWrapper::ChatTypeSecret: + break; + } + return false; +} + bool ChatListModel::ChatData::updateUnreadCount(int count) { const int prevUnreadCount(unreadCount()); @@ -195,7 +251,30 @@ QVector ChatListModel::ChatData::updateLastMessage(const QVariantMap &messa return changedRoles; } -ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) +QVector ChatListModel::ChatData::updateGroup(const TDLibWrapper::Group *group) +{ + QVector changedRoles; + + if (group && groupId == group->groupId) { + const TDLibWrapper::ChatMemberStatus groupMemberStatus = group->chatMemberStatus(); + if (memberStatus != groupMemberStatus) { + memberStatus = groupMemberStatus; + changedRoles.append(RoleChatMemberStatus); + } + } + return changedRoles; +} + +TDLibWrapper::ChatType ChatListModel::ChatData::chatTypeFromString(const QString &type) +{ + return (type == TYPE_CHAT_TYPE_PRIVATE) ? TDLibWrapper::ChatTypePrivate : + (type == TYPE_CHAT_TYPE_BASIC_GROUP) ? TDLibWrapper::ChatTypeBasicGroup : + (type == TYPE_CHAT_TYPE_SUPERGROUP) ? TDLibWrapper::ChatTypeSupergroup : + (type == TYPE_CHAT_TYPE_SECRET) ? TDLibWrapper::ChatTypeSecret : + TDLibWrapper::ChatTypeUnknown; +} + +ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false) { this->tdLibWrapper = tdLibWrapper; connect(tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap))); @@ -205,6 +284,8 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) connect(tdLibWrapper, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SLOT(handleChatReadOutboxUpdated(QString, QString))); connect(tdLibWrapper, SIGNAL(messageSendSucceeded(QString, QString, QVariantMap)), this, SLOT(handleMessageSendSucceeded(QString, QString, QVariantMap))); connect(tdLibWrapper, SIGNAL(chatNotificationSettingsUpdated(QString, QVariantMap)), this, SLOT(handleChatNotificationSettingsUpdated(QString, QVariantMap))); + connect(tdLibWrapper, SIGNAL(superGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong))); + connect(tdLibWrapper, SIGNAL(basicGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong))); // Don't start the timer until we have at least one chat relativeTimeRefreshTimer = new QTimer(this); @@ -217,6 +298,7 @@ ChatListModel::~ChatListModel() { LOG("Destroying myself..."); qDeleteAll(chatList); + qDeleteAll(hiddenChats.values()); } QHash ChatListModel::roleNames() const @@ -224,6 +306,7 @@ QHash ChatListModel::roleNames() const QHash roles; roles.insert(ChatData::RoleDisplay, "display"); roles.insert(ChatData::RoleChatId, "chat_id"); + roles.insert(ChatData::RoleChatType, "chat_type"); roles.insert(ChatData::RoleTitle, "title"); roles.insert(ChatData::RolePhotoSmall, "photo_small"); roles.insert(ChatData::RoleUnreadCount, "unread_count"); @@ -231,6 +314,7 @@ QHash ChatListModel::roleNames() const roles.insert(ChatData::RoleLastMessageSenderId, "last_message_sender_id"); roles.insert(ChatData::RoleLastMessageDate, "last_message_date"); roles.insert(ChatData::RoleLastMessageText, "last_message_text"); + roles.insert(ChatData::RoleChatMemberStatus, "chat_member_status"); roles.insert(ChatData::RoleIsChannel, "is_channel"); return roles; } @@ -248,6 +332,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const switch ((ChatData::Role)role) { case ChatData::RoleDisplay: return data->chatData; case ChatData::RoleChatId: return data->chatId; + case ChatData::RoleChatType: return data->chatType; case ChatData::RoleTitle: return data->title(); case ChatData::RolePhotoSmall: return data->photoSmall(); case ChatData::RoleUnreadCount: return data->unreadCount(); @@ -255,6 +340,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const case ChatData::RoleLastMessageSenderId: return data->senderUserId(); case ChatData::RoleLastMessageText: return data->senderMessageText(); case ChatData::RoleLastMessageDate: return data->senderMessageDate(); + case ChatData::RoleChatMemberStatus: return data->memberStatus; case ChatData::RoleIsChannel: return data->isChannel(); } } @@ -307,107 +393,237 @@ int ChatListModel::updateChatOrder(int chatIndex) return newIndex; } -void ChatListModel::handleChatDiscovered(const QString &chatId, const QVariantMap &chatToBeAdded) +void ChatListModel::addVisibleChat(ChatData *chat) { - ChatData *chat = new ChatData(chatToBeAdded, tdLibWrapper->getUserInformation()); const int n = chatList.size(); - int chatIndex; - for (chatIndex = 0; chatIndex < n && chat->compareTo(chatList.at(chatIndex)) >= 0; chatIndex++); - LOG("Adding new chat" << chatId << "at" << chatIndex); - beginInsertRows(QModelIndex(), chatIndex, chatIndex); - chatList.insert(chatIndex, chat); - chatIndexMap.insert(chat->chatId, chatIndex); + int pos; + for (pos = 0; pos < n && chat->compareTo(chatList.at(pos)) >= 0; pos++); + LOG("Adding chat" << chat->chatId << "at" << pos); + beginInsertRows(QModelIndex(), pos, pos); + chatList.insert(pos, chat); + chatIndexMap.insert(chat->chatId, pos); // Update damaged part of the map - for (int i = chatIndex + 1; i <= n; i++) { + for (int i = pos + 1; i <= n; i++) { chatIndexMap.insert(chatList.at(i)->chatId, i); } endInsertRows(); - - // Start timestamp refresh timer when the first chat is discovered - if (!relativeTimeRefreshTimer->isActive()) { - relativeTimeRefreshTimer->start(); - } } -void ChatListModel::handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage) +void ChatListModel::updateChatVisibility(const TDLibWrapper::Group *group) { - if (chatIndexMap.contains(chatId)) { - int chatIndex = chatIndexMap.value(chatId); - LOG("Updating last message for chat" << chatId <<" at index" << chatIndex << "new order" << order); - ChatData *chat = chatList.at(chatIndex); - if (chat->setOrder(order)) { - chatIndex = updateChatOrder(chatIndex); + // See if any group has been removed from from view + for (int i = 0; i < chatList.size(); i++) { + ChatData *chat = chatList.at(i); + const QVector changedRoles(chat->updateGroup(group)); + if (chat->isHidden() && !showHiddenChats) { + LOG("Hiding chat" << chat->chatId << "at" << i); + beginRemoveRows(QModelIndex(), i, i); + chatList.removeAt(i); + // Update damaged part of the map + const int n = chatList.size(); + for (int pos = i; pos < n; pos++) { + chatIndexMap.insert(chatList.at(pos)->chatId, pos); + } + i--; + hiddenChats.insert(chat->chatId, chat); + endRemoveRows(); + } else if (!changedRoles.isEmpty()) { + const QModelIndex modelIndex(index(i)); + emit dataChanged(modelIndex, modelIndex, changedRoles); } - const QModelIndex modelIndex(index(chatIndex)); - emit dataChanged(modelIndex, modelIndex, chat->updateLastMessage(lastMessage)); } -} -void ChatListModel::handleChatOrderUpdated(const QString &chatId, const QString &order) -{ - if (chatIndexMap.contains(chatId)) { - LOG("Updating chat order of" << chatId << "to" << order); - int chatIndex = chatIndexMap.value(chatId); - if (chatList.at(chatIndex)->setOrder(order)) { - updateChatOrder(chatIndex); + // And see if any group been added to the view + const QList hiddenChatList = hiddenChats.values(); + const int n = hiddenChatList.size(); + for (int j = 0; j < n; j++) { + ChatData *chat = hiddenChatList.at(j); + chat->updateGroup(group); + if (!chat->isHidden() || showHiddenChats) { + hiddenChats.remove(chat->chatId); + addVisibleChat(chat); } } } -void ChatListModel::handleChatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount) +bool ChatListModel::showAllChats() const { - if (chatIndexMap.contains(chatId)) { - LOG("Updating chat unread count for" << chatId << "unread messages" << unreadCount << ", last read message ID: " << lastReadInboxMessageId); - const int chatIndex = chatIndexMap.value(chatId); - ChatData *chat = chatList.at(chatIndex); - QVector changedRoles; - changedRoles.append(ChatData::RoleDisplay); - if (chat->updateUnreadCount(unreadCount)) { - changedRoles.append(ChatData::RoleUnreadCount); - } - if (chat->updateLastReadInboxMessageId(lastReadInboxMessageId.toLongLong())) { - changedRoles.append(ChatData::RoleLastReadInboxMessageId); - } - const QModelIndex modelIndex(index(chatIndex)); - emit dataChanged(modelIndex, modelIndex, changedRoles); + return showHiddenChats; +} + +void ChatListModel::setShowAllChats(bool showAll) +{ + if (showHiddenChats != showAll) { + showHiddenChats = showAll; + updateChatVisibility(Q_NULLPTR); + emit showAllChatsChanged(); } } -void ChatListModel::handleChatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId) +void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded) { - if (chatIndexMap.contains(chatId)) { - LOG("Updating last read message for" << chatId << "last ID" << lastReadOutboxMessageId); - const int chatIndex = chatIndexMap.value(chatId); - ChatData *chat = chatList.at(chatIndex); - chat->chatData.insert(LAST_READ_OUTBOX_MESSAGE_ID, lastReadOutboxMessageId); - const QModelIndex modelIndex(index(chatIndex)); - emit dataChanged(modelIndex, modelIndex); + ChatData *chat = new ChatData(chatToBeAdded, tdLibWrapper->getUserInformation()); + const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId); + if (group) { + chat->updateGroup(group); + } + if (chat->isHidden()) { + LOG("Hidden chat" << chat->chatId); + hiddenChats.insert(chat->chatId, chat); + } else { + addVisibleChat(chat); + + // Start timestamp refresh timer when the first visible chat is discovered + if (!relativeTimeRefreshTimer->isActive()) { + relativeTimeRefreshTimer->start(); + } + } +} + +void ChatListModel::handleChatLastMessageUpdated(const QString &id, const QString &order, const QVariantMap &lastMessage) +{ + bool ok; + const qlonglong chatId = id.toLongLong(&ok); + if (ok) { + if (chatIndexMap.contains(chatId)) { + int chatIndex = chatIndexMap.value(chatId); + LOG("Updating last message for chat" << chatId <<" at index" << chatIndex << "new order" << order); + ChatData *chat = chatList.at(chatIndex); + if (chat->setOrder(order)) { + chatIndex = updateChatOrder(chatIndex); + } + const QModelIndex modelIndex(index(chatIndex)); + emit dataChanged(modelIndex, modelIndex, chat->updateLastMessage(lastMessage)); + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + LOG("Updating last message for hidden chat" << chatId << "new order" << order); + chat->setOrder(order); + chat->chatData.insert(LAST_MESSAGE, lastMessage); + } + } + } +} + +void ChatListModel::handleChatOrderUpdated(const QString &id, const QString &order) +{ + bool ok; + const qlonglong chatId = id.toLongLong(&ok); + if (ok) { + if (chatIndexMap.contains(chatId)) { + LOG("Updating chat order of" << chatId << "to" << order); + int chatIndex = chatIndexMap.value(chatId); + if (chatList.at(chatIndex)->setOrder(order)) { + updateChatOrder(chatIndex); + } + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + LOG("Updating order of hidden chat" << chatId << "to" << order); + chat->setOrder(order); + } + } + } +} + +void ChatListModel::handleChatReadInboxUpdated(const QString &id, const QString &lastReadInboxMessageId, int unreadCount) +{ + bool ok; + const qlonglong chatId = id.toLongLong(&ok); + if (ok) { + const qlonglong messageId = lastReadInboxMessageId.toLongLong(); + if (chatIndexMap.contains(chatId)) { + LOG("Updating chat unread count for" << chatId << "unread messages" << unreadCount << ", last read message ID: " << lastReadInboxMessageId); + const int chatIndex = chatIndexMap.value(chatId); + ChatData *chat = chatList.at(chatIndex); + QVector changedRoles; + changedRoles.append(ChatData::RoleDisplay); + if (chat->updateUnreadCount(unreadCount)) { + changedRoles.append(ChatData::RoleUnreadCount); + } + if (chat->updateLastReadInboxMessageId(messageId)) { + changedRoles.append(ChatData::RoleLastReadInboxMessageId); + } + const QModelIndex modelIndex(index(chatIndex)); + emit dataChanged(modelIndex, modelIndex, changedRoles); + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + LOG("Updating unread count for hidden chat" << chatId << "unread messages" << unreadCount << ", last read message ID: " << lastReadInboxMessageId); + chat->updateUnreadCount(unreadCount); + chat->updateLastReadInboxMessageId(messageId); + } + } + } +} + +void ChatListModel::handleChatReadOutboxUpdated(const QString &id, const QString &lastReadOutboxMessageId) +{ + bool ok; + const qlonglong chatId = id.toLongLong(&ok); + if (ok) { + if (chatIndexMap.contains(chatId)) { + LOG("Updating last read message for" << chatId << "last ID" << lastReadOutboxMessageId); + const int chatIndex = chatIndexMap.value(chatId); + ChatData *chat = chatList.at(chatIndex); + chat->chatData.insert(LAST_READ_OUTBOX_MESSAGE_ID, lastReadOutboxMessageId); + const QModelIndex modelIndex(index(chatIndex)); + emit dataChanged(modelIndex, modelIndex); + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + chat->chatData.insert(LAST_READ_OUTBOX_MESSAGE_ID, lastReadOutboxMessageId); + } + } } } void ChatListModel::handleMessageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message) { - const QString chatId(message.value(CHAT_ID).toString()); - if (chatIndexMap.contains(chatId)) { - const int chatIndex = chatIndexMap.value(chatId); - LOG("Updating last message for chat" << chatId << "at index" << chatIndex << ", as message was sent, old ID:" << oldMessageId << ", new ID:" << messageId); - const QModelIndex modelIndex(index(chatIndex)); - emit dataChanged(modelIndex, modelIndex, chatList.at(chatIndex)->updateLastMessage(message)); + bool ok; + const qlonglong chatId(message.value(CHAT_ID).toLongLong(&ok)); + if (ok) { + if (chatIndexMap.contains(chatId)) { + const int chatIndex = chatIndexMap.value(chatId); + LOG("Updating last message for chat" << chatId << "at index" << chatIndex << ", as message was sent, old ID:" << oldMessageId << ", new ID:" << messageId); + const QModelIndex modelIndex(index(chatIndex)); + emit dataChanged(modelIndex, modelIndex, chatList.at(chatIndex)->updateLastMessage(message)); + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + LOG("Updating last message for hidden chat" << chatId << ", as message was sent, old ID:" << oldMessageId << ", new ID:" << messageId); + chat->chatData.insert(LAST_MESSAGE, message); + } + } } } -void ChatListModel::handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings) +void ChatListModel::handleChatNotificationSettingsUpdated(const QString &id, const QVariantMap &chatNotificationSettings) { - if (chatIndexMap.contains(chatId)) { - const int chatIndex = chatIndexMap.value(chatId); - LOG("Updating notification settings for chat" << chatId << "at index" << chatIndex); - ChatData *chat = chatList.at(chatIndex); - chat->chatData.insert(NOTIFICATION_SETTINGS, chatNotificationSettings); - const QModelIndex modelIndex(index(chatIndex)); - emit dataChanged(modelIndex, modelIndex); + bool ok; + const qlonglong chatId = id.toLongLong(&ok); + if (ok) { + if (chatIndexMap.contains(chatId)) { + const int chatIndex = chatIndexMap.value(chatId); + LOG("Updating notification settings for chat" << chatId << "at index" << chatIndex); + ChatData *chat = chatList.at(chatIndex); + chat->chatData.insert(NOTIFICATION_SETTINGS, chatNotificationSettings); + const QModelIndex modelIndex(index(chatIndex)); + emit dataChanged(modelIndex, modelIndex); + } else { + ChatData *chat = hiddenChats.value(chatId); + if (chat) { + chat->chatData.insert(NOTIFICATION_SETTINGS, chatNotificationSettings); + } + } } } +void ChatListModel::handleGroupUpdated(qlonglong groupId) +{ + updateChatVisibility(tdLibWrapper->getGroup(groupId)); +} + void ChatListModel::handleRelativeTimeRefreshTimer() { LOG("Refreshing timestamps"); diff --git a/src/chatlistmodel.h b/src/chatlistmodel.h index 485b0cc..f89b804 100644 --- a/src/chatlistmodel.h +++ b/src/chatlistmodel.h @@ -26,6 +26,8 @@ class ChatListModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(bool showAllChats READ showAllChats WRITE setShowAllChats NOTIFY showAllChatsChanged) + public: ChatListModel(TDLibWrapper *tdLibWrapper); ~ChatListModel() override; @@ -36,6 +38,9 @@ public: Q_INVOKABLE void redrawModel(); + bool showAllChats() const; + void setShowAllChats(bool showAll); + private slots: void handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation); void handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage); @@ -44,18 +49,25 @@ private slots: void handleChatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId); void handleMessageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message); void handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings); + void handleGroupUpdated(qlonglong groupId); void handleRelativeTimeRefreshTimer(); -private: - int updateChatOrder(int chatIndex); +signals: + void showAllChatsChanged(); private: class ChatData; + void addVisibleChat(ChatData *chat); + void updateChatVisibility(const TDLibWrapper::Group *group); + int updateChatOrder(int chatIndex); +private: TDLibWrapper *tdLibWrapper; QTimer *relativeTimeRefreshTimer; QList chatList; - QHash chatIndexMap; + QHash chatIndexMap; + QHash hiddenChats; + bool showHiddenChats; }; #endif // CHATLISTMODEL_H diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp index b091cee..a308a7e 100644 --- a/src/tdlibreceiver.cpp +++ b/src/tdlibreceiver.cpp @@ -27,6 +27,8 @@ namespace { const QString POSITION("position"); const QString POSITIONS("positions"); const QString ORDER("order"); + const QString BASIC_GROUP("basic_group"); + const QString SUPERGROUP("supergroup"); const QString LAST_MESSAGE("last_message"); const QString UNREAD_COUNT("unread_count"); const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id"); @@ -264,16 +266,18 @@ void TDLibReceiver::processUpdateChatReadOutbox(const QVariantMap &receivedInfor void TDLibReceiver::processUpdateBasicGroup(const QVariantMap &receivedInformation) { - QString basicGroupId = receivedInformation.value("basic_group").toMap().value(ID).toString(); + const QVariantMap basicGroup(receivedInformation.value(BASIC_GROUP).toMap()); + const qlonglong basicGroupId = basicGroup.value(ID).toLongLong(); LOG("Basic group information updated for " << basicGroupId); - emit basicGroupUpdated(basicGroupId, receivedInformation.value("basic_group").toMap()); + emit basicGroupUpdated(basicGroupId, basicGroup); } void TDLibReceiver::processUpdateSuperGroup(const QVariantMap &receivedInformation) { - QString superGroupId = receivedInformation.value("supergroup").toMap().value(ID).toString(); + const QVariantMap supergroup(receivedInformation.value(SUPERGROUP).toMap()); + const qlonglong superGroupId = supergroup.value(ID).toLongLong(); LOG("Super group information updated for " << superGroupId); - emit superGroupUpdated(superGroupId, receivedInformation.value("supergroup").toMap()); + emit superGroupUpdated(superGroupId, supergroup); } void TDLibReceiver::processChatOnlineMemberCountUpdated(const QVariantMap &receivedInformation) diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h index 3434710..ec2a343 100644 --- a/src/tdlibreceiver.h +++ b/src/tdlibreceiver.h @@ -50,8 +50,8 @@ signals: void chatOrderUpdated(const QString &chatId, const QString &order); void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount); void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId); - void basicGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); - void superGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); + void basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation); + void superGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation); void chatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount); void messagesReceived(const QVariantList &messages); void newMessageReceived(const QString &chatId, const QVariantMap &message); diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp index e1dfffc..af11fd4 100644 --- a/src/tdlibwrapper.cpp +++ b/src/tdlibwrapper.cpp @@ -38,6 +38,11 @@ # define VERBOSE(x) #endif +namespace { + const QString STATUS("status"); + const QString _TYPE("@type"); +} + TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent), settings("harbour-fernschreiber", "settings") { LOG("Initializing TD Lib..."); @@ -67,8 +72,8 @@ TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent), settings("harbour connect(this->tdLibReceiver, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString))); connect(this->tdLibReceiver, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SLOT(handleChatReadInboxUpdated(QString, QString, int))); connect(this->tdLibReceiver, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SLOT(handleChatReadOutboxUpdated(QString, QString))); - connect(this->tdLibReceiver, SIGNAL(basicGroupUpdated(QString, QVariantMap)), this, SLOT(handleBasicGroupUpdated(QString, QVariantMap))); - connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(QString, QVariantMap)), this, SLOT(handleSuperGroupUpdated(QString, QVariantMap))); + connect(this->tdLibReceiver, SIGNAL(basicGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleBasicGroupUpdated(qlonglong, QVariantMap))); + connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleSuperGroupUpdated(qlonglong, QVariantMap))); connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SLOT(handleChatOnlineMemberCountUpdated(QString, int))); connect(this->tdLibReceiver, SIGNAL(messagesReceived(QVariantList)), this, SLOT(handleMessagesReceived(QVariantList))); connect(this->tdLibReceiver, SIGNAL(newMessageReceived(QString, QVariantMap)), this, SLOT(handleNewMessageReceived(QString, QVariantMap))); @@ -94,12 +99,14 @@ TDLibWrapper::~TDLibWrapper() while (this->tdLibReceiver->isRunning()) { QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); } + qDeleteAll(basicGroups.values()); + qDeleteAll(superGroups.values()); td_json_client_destroy(this->tdLibClient); } void TDLibWrapper::sendRequest(const QVariantMap &requestObject) { - LOG("Sending request to TD Lib, object type name:" << requestObject.value("@type").toString()); + LOG("Sending request to TD Lib, object type name:" << requestObject.value(_TYPE).toString()); QJsonDocument requestDocument = QJsonDocument::fromVariant(requestObject); VERBOSE(requestDocument.toJson().constData()); td_json_client_send(this->tdLibClient, requestDocument.toJson().constData()); @@ -124,7 +131,7 @@ void TDLibWrapper::setAuthenticationPhoneNumber(const QString &phoneNumber) { LOG("Set authentication phone number " << phoneNumber); QVariantMap requestObject; - requestObject.insert("@type", "setAuthenticationPhoneNumber"); + requestObject.insert(_TYPE, "setAuthenticationPhoneNumber"); requestObject.insert("phone_number", phoneNumber); QVariantMap phoneNumberSettings; phoneNumberSettings.insert("allow_flash_call", false); @@ -137,7 +144,7 @@ void TDLibWrapper::setAuthenticationCode(const QString &authenticationCode) { LOG("Set authentication code " << authenticationCode); QVariantMap requestObject; - requestObject.insert("@type", "checkAuthenticationCode"); + requestObject.insert(_TYPE, "checkAuthenticationCode"); requestObject.insert("code", authenticationCode); this->sendRequest(requestObject); } @@ -146,7 +153,7 @@ void TDLibWrapper::setAuthenticationPassword(const QString &authenticationPasswo { LOG("Set authentication password " << authenticationPassword); QVariantMap requestObject; - requestObject.insert("@type", "checkAuthenticationPassword"); + requestObject.insert(_TYPE, "checkAuthenticationPassword"); requestObject.insert("password", authenticationPassword); this->sendRequest(requestObject); } @@ -155,7 +162,7 @@ void TDLibWrapper::getChats() { LOG("Getting chats"); QVariantMap requestObject; - requestObject.insert("@type", "getChats"); + requestObject.insert(_TYPE, "getChats"); requestObject.insert("limit", 5); this->sendRequest(requestObject); } @@ -164,7 +171,7 @@ void TDLibWrapper::downloadFile(const QString &fileId) { LOG("Downloading file " << fileId); QVariantMap requestObject; - requestObject.insert("@type", "downloadFile"); + requestObject.insert(_TYPE, "downloadFile"); requestObject.insert("file_id", fileId); requestObject.insert("synchronous", false); requestObject.insert("offset", 0); @@ -177,7 +184,7 @@ void TDLibWrapper::openChat(const QString &chatId) { LOG("Opening chat " << chatId); QVariantMap requestObject; - requestObject.insert("@type", "openChat"); + requestObject.insert(_TYPE, "openChat"); requestObject.insert("chat_id", chatId); this->sendRequest(requestObject); } @@ -186,7 +193,7 @@ void TDLibWrapper::closeChat(const QString &chatId) { LOG("Closing chat " << chatId); QVariantMap requestObject; - requestObject.insert("@type", "closeChat"); + requestObject.insert(_TYPE, "closeChat"); requestObject.insert("chat_id", chatId); this->sendRequest(requestObject); } @@ -195,7 +202,7 @@ void TDLibWrapper::getChatHistory(const QString &chatId, const qlonglong &fromMe { LOG("Retrieving chat history" << chatId << fromMessageId << offset << limit << onlyLocal); QVariantMap requestObject; - requestObject.insert("@type", "getChatHistory"); + requestObject.insert(_TYPE, "getChatHistory"); requestObject.insert("chat_id", chatId); requestObject.insert("from_message_id", fromMessageId); requestObject.insert("offset", offset); @@ -208,7 +215,7 @@ void TDLibWrapper::viewMessage(const QString &chatId, const QString &messageId) { LOG("Mark message as viewed" << chatId << messageId); QVariantMap requestObject; - requestObject.insert("@type", "viewMessages"); + requestObject.insert(_TYPE, "viewMessages"); requestObject.insert("chat_id", chatId); requestObject.insert("force_read", false); QVariantList messageIds; @@ -221,16 +228,16 @@ void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message { LOG("Sending text message" << chatId << message << replyToMessageId); QVariantMap requestObject; - requestObject.insert("@type", "sendMessage"); + requestObject.insert(_TYPE, "sendMessage"); requestObject.insert("chat_id", chatId); if (replyToMessageId != "0") { requestObject.insert("reply_to_message_id", replyToMessageId); } QVariantMap inputMessageContent; - inputMessageContent.insert("@type", "inputMessageText"); + inputMessageContent.insert(_TYPE, "inputMessageText"); QVariantMap formattedText; formattedText.insert("text", message); - formattedText.insert("@type", "formattedText"); + formattedText.insert(_TYPE, "formattedText"); inputMessageContent.insert("text", formattedText); requestObject.insert("input_message_content", inputMessageContent); this->sendRequest(requestObject); @@ -240,19 +247,19 @@ void TDLibWrapper::sendPhotoMessage(const QString &chatId, const QString &filePa { LOG("Sending photo message" << chatId << filePath << message << replyToMessageId); QVariantMap requestObject; - requestObject.insert("@type", "sendMessage"); + requestObject.insert(_TYPE, "sendMessage"); requestObject.insert("chat_id", chatId); if (replyToMessageId != "0") { requestObject.insert("reply_to_message_id", replyToMessageId); } QVariantMap inputMessageContent; - inputMessageContent.insert("@type", "inputMessagePhoto"); + inputMessageContent.insert(_TYPE, "inputMessagePhoto"); QVariantMap formattedText; formattedText.insert("text", message); - formattedText.insert("@type", "formattedText"); + formattedText.insert(_TYPE, "formattedText"); inputMessageContent.insert("caption", formattedText); QVariantMap photoInputFile; - photoInputFile.insert("@type", "inputFileLocal"); + photoInputFile.insert(_TYPE, "inputFileLocal"); photoInputFile.insert("path", filePath); inputMessageContent.insert("photo", photoInputFile); @@ -264,19 +271,19 @@ void TDLibWrapper::sendVideoMessage(const QString &chatId, const QString &filePa { LOG("Sending video message" << chatId << filePath << message << replyToMessageId); QVariantMap requestObject; - requestObject.insert("@type", "sendMessage"); + requestObject.insert(_TYPE, "sendMessage"); requestObject.insert("chat_id", chatId); if (replyToMessageId != "0") { requestObject.insert("reply_to_message_id", replyToMessageId); } QVariantMap inputMessageContent; - inputMessageContent.insert("@type", "inputMessageVideo"); + inputMessageContent.insert(_TYPE, "inputMessageVideo"); QVariantMap formattedText; formattedText.insert("text", message); - formattedText.insert("@type", "formattedText"); + formattedText.insert(_TYPE, "formattedText"); inputMessageContent.insert("caption", formattedText); QVariantMap videoInputFile; - videoInputFile.insert("@type", "inputFileLocal"); + videoInputFile.insert(_TYPE, "inputFileLocal"); videoInputFile.insert("path", filePath); inputMessageContent.insert("video", videoInputFile); @@ -288,19 +295,19 @@ void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &fil { LOG("Sending document message" << chatId << filePath << message << replyToMessageId); QVariantMap requestObject; - requestObject.insert("@type", "sendMessage"); + requestObject.insert(_TYPE, "sendMessage"); requestObject.insert("chat_id", chatId); if (replyToMessageId != "0") { requestObject.insert("reply_to_message_id", replyToMessageId); } QVariantMap inputMessageContent; - inputMessageContent.insert("@type", "inputMessageDocument"); + inputMessageContent.insert(_TYPE, "inputMessageDocument"); QVariantMap formattedText; formattedText.insert("text", message); - formattedText.insert("@type", "formattedText"); + formattedText.insert(_TYPE, "formattedText"); inputMessageContent.insert("caption", formattedText); QVariantMap documentInputFile; - documentInputFile.insert("@type", "inputFileLocal"); + documentInputFile.insert(_TYPE, "inputFileLocal"); documentInputFile.insert("path", filePath); inputMessageContent.insert("document", documentInputFile); @@ -312,7 +319,7 @@ void TDLibWrapper::getMessage(const QString &chatId, const QString &messageId) { LOG("Retrieving message" << chatId << messageId); QVariantMap requestObject; - requestObject.insert("@type", "getMessage"); + requestObject.insert(_TYPE, "getMessage"); requestObject.insert("chat_id", chatId); requestObject.insert("message_id", messageId); this->sendRequest(requestObject); @@ -322,10 +329,10 @@ void TDLibWrapper::setOptionInteger(const QString &optionName, const int &option { LOG("Setting integer option" << optionName << optionValue); QVariantMap requestObject; - requestObject.insert("@type", "setOption"); + requestObject.insert(_TYPE, "setOption"); requestObject.insert("name", optionName); QVariantMap optionValueMap; - optionValueMap.insert("@type", "optionValueInteger"); + optionValueMap.insert(_TYPE, "optionValueInteger"); optionValueMap.insert("value", optionValue); requestObject.insert("value", optionValueMap); this->sendRequest(requestObject); @@ -335,7 +342,7 @@ void TDLibWrapper::setChatNotificationSettings(const QString &chatId, const QVar { LOG("Notification settings for chat " << chatId << notificationSettings); QVariantMap requestObject; - requestObject.insert("@type", "setChatNotificationSettings"); + requestObject.insert(_TYPE, "setChatNotificationSettings"); requestObject.insert("chat_id", chatId); requestObject.insert("notification_settings", notificationSettings); this->sendRequest(requestObject); @@ -345,11 +352,11 @@ void TDLibWrapper::editMessageText(const QString &chatId, const QString &message { LOG("Editing message text" << chatId << messageId); QVariantMap requestObject; - requestObject.insert("@type", "editMessageText"); + requestObject.insert(_TYPE, "editMessageText"); requestObject.insert("chat_id", chatId); requestObject.insert("message_id", messageId); QVariantMap inputMessageContent; - inputMessageContent.insert("@type", "inputMessageText"); + inputMessageContent.insert(_TYPE, "inputMessageText"); QVariantMap formattedText; formattedText.insert("text", message); inputMessageContent.insert("text", formattedText); @@ -361,7 +368,7 @@ void TDLibWrapper::deleteMessages(const QString &chatId, const QVariantList mess { LOG("Deleting some messages" << chatId << messageIds); QVariantMap requestObject; - requestObject.insert("@type", "deleteMessages"); + requestObject.insert(_TYPE, "deleteMessages"); requestObject.insert("chat_id", chatId); requestObject.insert("message_ids", messageIds); requestObject.insert("revoke", true); @@ -380,7 +387,7 @@ void TDLibWrapper::getMapThumbnailFile(const QString &chatId, const double &lati int boundsHeight = std::min(std::max(height, 16), 1024); QVariantMap requestObject; - requestObject.insert("@type", "getMapThumbnailFile"); + requestObject.insert(_TYPE, "getMapThumbnailFile"); requestObject.insert("location", location); requestObject.insert("zoom", 17); //13-20 requestObject.insert("width", boundsWidth); @@ -412,16 +419,28 @@ QVariantMap TDLibWrapper::getUnreadChatInformation() return this->unreadChatInformation; } -QVariantMap TDLibWrapper::getBasicGroup(const QString &groupId) +QVariantMap TDLibWrapper::getBasicGroup(qlonglong groupId) const { - LOG("Returning basic group information for ID" << groupId); - return this->basicGroups.value(groupId).toMap(); + const Group* group = basicGroups.value(groupId); + if (group) { + LOG("Returning basic group information for ID" << groupId); + return group->groupInfo; + } else { + LOG("No super group information for ID" << groupId); + return QVariantMap(); + } } -QVariantMap TDLibWrapper::getSuperGroup(const QString &groupId) +QVariantMap TDLibWrapper::getSuperGroup(qlonglong groupId) const { - LOG("Returning super group information for ID" << groupId); - return this->superGroups.value(groupId).toMap(); + const Group* group = superGroups.value(groupId); + if (group) { + LOG("Returning super group information for ID" << groupId); + return group->groupInfo; + } else { + LOG("No super group information for ID" << groupId); + return QVariantMap(); + } } QVariantMap TDLibWrapper::getChat(const QString &chatId) @@ -595,7 +614,7 @@ void TDLibWrapper::handleUserStatusUpdated(const QString &userId, const QVariant LOG("Own user status information updated :)"); this->userInformation.insert("status", userStatusInformation); } - LOG("User status information updated:" << userId << userStatusInformation.value("@type").toString()); + LOG("User status information updated:" << userId << userStatusInformation.value(_TYPE).toString()); QVariantMap updatedUserInformation = this->allUsers.value(userId).toMap(); updatedUserInformation.insert("status", userStatusInformation); this->allUsers.insert(userId, updatedUserInformation); @@ -650,16 +669,14 @@ void TDLibWrapper::handleChatReadOutboxUpdated(const QString &chatId, const QStr emit chatReadOutboxUpdated(chatId, lastReadOutboxMessageId); } -void TDLibWrapper::handleBasicGroupUpdated(const QString &groupId, const QVariantMap &groupInformation) +void TDLibWrapper::handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation) { - this->basicGroups.insert(groupId, groupInformation); - emit basicGroupUpdated(groupId, groupInformation); + emit basicGroupUpdated(updateGroup(groupId, groupInformation, &basicGroups)->groupId); } -void TDLibWrapper::handleSuperGroupUpdated(const QString &groupId, const QVariantMap &groupInformation) +void TDLibWrapper::handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation) { - this->superGroups.insert(groupId, groupInformation); - emit superGroupUpdated(groupId, groupInformation); + emit superGroupUpdated(updateGroup(groupId, groupInformation, &superGroups)->groupId); } void TDLibWrapper::handleChatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount) @@ -721,7 +738,7 @@ void TDLibWrapper::setInitialParameters() { LOG("Sending initial parameters to TD Lib"); QVariantMap requestObject; - requestObject.insert("@type", "setTdlibParameters"); + requestObject.insert(_TYPE, "setTdlibParameters"); QVariantMap initialParameters; initialParameters.insert("api_id", TDLIB_API_ID); initialParameters.insert("api_hash", TDLIB_API_HASH); @@ -743,7 +760,7 @@ void TDLibWrapper::setEncryptionKey() { LOG("Setting database encryption key"); QVariantMap requestObject; - requestObject.insert("@type", "checkDatabaseEncryptionKey"); + requestObject.insert(_TYPE, "checkDatabaseEncryptionKey"); // see https://github.com/tdlib/td/issues/188#issuecomment-379536139 requestObject.insert("encryption_key", ""); this->sendRequest(requestObject); @@ -753,7 +770,7 @@ void TDLibWrapper::setLogVerbosityLevel() { LOG("Setting log verbosity level to something less chatty"); QVariantMap requestObject; - requestObject.insert("@type", "setLogVerbosityLevel"); + requestObject.insert(_TYPE, "setLogVerbosityLevel"); requestObject.insert("new_verbosity_level", 2); this->sendRequest(requestObject); } @@ -784,3 +801,40 @@ void TDLibWrapper::initializeOpenWith() } } +const TDLibWrapper::Group *TDLibWrapper::updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups) +{ + Group* group = groups->value(groupId); + if (!group) { + group = new Group(groupId); + groups->insert(groupId, group); + } + group->groupInfo = groupInfo; + return group; +} + +const TDLibWrapper::Group* TDLibWrapper::getGroup(qlonglong groupId) const +{ + if (groupId) { + const Group* group = superGroups.value(groupId); + return group ? group : basicGroups.value(groupId); + } + return Q_NULLPTR; +} + +TDLibWrapper::ChatMemberStatus TDLibWrapper::chatMemberStatusFromString(const QString &status) +{ + // Most common ones first + return (status == QStringLiteral("chatMemberStatusMember")) ? ChatMemberStatusMember : + (status == QStringLiteral("chatMemberStatusLeft")) ? ChatMemberStatusLeft : + (status == QStringLiteral("chatMemberStatusCreator")) ? ChatMemberStatusCreator : + (status == QStringLiteral("chatMemberStatusAdministrator")) ? ChatMemberStatusAdministrator : + (status == QStringLiteral("chatMemberStatusRestricted")) ? ChatMemberStatusRestricted : + (status == QStringLiteral("chatMemberStatusBanned")) ? ChatMemberStatusBanned : + ChatMemberStatusUnknown; +} + +TDLibWrapper::ChatMemberStatus TDLibWrapper::Group::chatMemberStatus() const +{ + const QString statusType(groupInfo.value(STATUS).toMap().value(_TYPE).toString()); + return statusType.isEmpty() ? ChatMemberStatusUnknown : chatMemberStatusFromString(statusType); +} diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h index 96cfd08..11517d0 100644 --- a/src/tdlibwrapper.h +++ b/src/tdlibwrapper.h @@ -61,6 +61,35 @@ public: }; Q_ENUM(ConnectionState) + enum ChatType { + ChatTypeUnknown, + ChatTypePrivate, + ChatTypeBasicGroup, + ChatTypeSupergroup, + ChatTypeSecret + }; + Q_ENUM(ChatType) + + enum ChatMemberStatus { + ChatMemberStatusUnknown, + ChatMemberStatusCreator, + ChatMemberStatusAdministrator, + ChatMemberStatusMember, + ChatMemberStatusRestricted, + ChatMemberStatusLeft, + ChatMemberStatusBanned + }; + Q_ENUM(ChatMemberStatus) + + class Group { + public: + Group(qlonglong id) : groupId(id) { } + ChatMemberStatus chatMemberStatus() const; + public: + const qlonglong groupId; + QVariantMap groupInfo; + }; + Q_INVOKABLE QString getVersion(); Q_INVOKABLE TDLibWrapper::AuthorizationState getAuthorizationState(); Q_INVOKABLE TDLibWrapper::ConnectionState getConnectionState(); @@ -68,8 +97,8 @@ public: Q_INVOKABLE QVariantMap getUserInformation(const QString &userId); Q_INVOKABLE QVariantMap getUnreadMessageInformation(); Q_INVOKABLE QVariantMap getUnreadChatInformation(); - Q_INVOKABLE QVariantMap getBasicGroup(const QString &groupId); - Q_INVOKABLE QVariantMap getSuperGroup(const QString &groupId); + Q_INVOKABLE QVariantMap getBasicGroup(qlonglong groupId) const; + Q_INVOKABLE QVariantMap getSuperGroup(qlonglong groupId) const; Q_INVOKABLE QVariantMap getChat(const QString &chatId); Q_INVOKABLE void copyFileToDownloads(const QString &filePath); Q_INVOKABLE void openFileOnDevice(const QString &filePath); @@ -101,6 +130,10 @@ public: Q_INVOKABLE void deleteMessages(const QString &chatId, const QVariantList messageIds); Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, const double &latitude, const double &longitude, const int &width, const int &height); +public: + const Group* getGroup(qlonglong groupId) const; + static ChatMemberStatus chatMemberStatusFromString(const QString &status); + signals: void versionDetected(const QString &version); void ownUserIdFound(const QString &ownUserId); @@ -116,8 +149,8 @@ signals: void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount); void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId); void userUpdated(const QString &userId, const QVariantMap &userInformation); - void basicGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); - void superGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); + void basicGroupUpdated(qlonglong groupId); + void superGroupUpdated(qlonglong groupId); void chatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount); void messagesReceived(const QVariantList &messages); void newMessageReceived(const QString &chatId, const QVariantMap &message); @@ -147,8 +180,8 @@ public slots: void handleChatOrderUpdated(const QString &chatId, const QString &order); void handleChatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount); void handleChatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId); - void handleBasicGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); - void handleSuperGroupUpdated(const QString &groupId, const QVariantMap &groupInformation); + void handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation); + void handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation); void handleChatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount); void handleMessagesReceived(const QVariantList &messages); void handleNewMessageReceived(const QString &chatId, const QVariantMap &message); @@ -161,6 +194,13 @@ public slots: void handleMessageContentUpdated(const QString &chatId, const QString &messageId, const QVariantMap &newContent); void handleMessagesDeleted(const QString &chatId, const QVariantList &messageIds); +private: + void setInitialParameters(); + void setEncryptionKey(); + void setLogVerbosityLevel(); + void initializeOpenWith(); + const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups); + private: void *tdLibClient; TDLibReceiver *tdLibReceiver; @@ -174,15 +214,9 @@ private: QVariantMap chats; QVariantMap unreadMessageInformation; QVariantMap unreadChatInformation; - QVariantMap basicGroups; - QVariantMap superGroups; + QHash basicGroups; + QHash superGroups; QSettings settings; - - void setInitialParameters(); - void setEncryptionKey(); - void setLogVerbosityLevel(); - void initializeOpenWith(); - }; #endif // TDLIBWRAPPER_H