Don't show irrelevant groups by default
chatListModel.showAllChats property can be used to switch visibility of irrelevant groups on and off.
This commit is contained in:
parent
1b261c224f
commit
56bc1135a7
6 changed files with 470 additions and 150 deletions
|
@ -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<int> updateLastMessage(const QVariantMap &message);
|
||||
QVector<int> 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<int> ChatListModel::ChatData::updateLastMessage(const QVariantMap &messa
|
|||
return changedRoles;
|
||||
}
|
||||
|
||||
ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper)
|
||||
QVector<int> ChatListModel::ChatData::updateGroup(const TDLibWrapper::Group *group)
|
||||
{
|
||||
QVector<int> 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<int,QByteArray> ChatListModel::roleNames() const
|
||||
|
@ -224,6 +306,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
|
|||
QHash<int,QByteArray> 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<int,QByteArray> 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<int> 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<ChatData*> 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<int> 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<int> 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");
|
||||
|
|
|
@ -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<ChatData*> chatList;
|
||||
QHash<QString,int> chatIndexMap;
|
||||
QHash<qlonglong,int> chatIndexMap;
|
||||
QHash<qlonglong,ChatData*> hiddenChats;
|
||||
bool showHiddenChats;
|
||||
};
|
||||
|
||||
#endif // CHATLISTMODEL_H
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<qlonglong,Group*> *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);
|
||||
}
|
||||
|
|
|
@ -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<qlonglong,Group*> *groups);
|
||||
|
||||
private:
|
||||
void *tdLibClient;
|
||||
TDLibReceiver *tdLibReceiver;
|
||||
|
@ -174,15 +214,9 @@ private:
|
|||
QVariantMap chats;
|
||||
QVariantMap unreadMessageInformation;
|
||||
QVariantMap unreadChatInformation;
|
||||
QVariantMap basicGroups;
|
||||
QVariantMap superGroups;
|
||||
QHash<qlonglong,Group*> basicGroups;
|
||||
QHash<qlonglong,Group*> superGroups;
|
||||
QSettings settings;
|
||||
|
||||
void setInitialParameters();
|
||||
void setEncryptionKey();
|
||||
void setLogVerbosityLevel();
|
||||
void initializeOpenWith();
|
||||
|
||||
};
|
||||
|
||||
#endif // TDLIBWRAPPER_H
|
||||
|
|
Loading…
Reference in a new issue