2020-02-23 14:02:47 +01:00
|
|
|
#include "account-data.h"
|
2020-07-25 12:49:38 +02:00
|
|
|
#include "client-utils.h"
|
2020-02-23 14:02:47 +01:00
|
|
|
#include "config.h"
|
2021-12-06 19:56:53 +01:00
|
|
|
#include "format.h"
|
2020-02-23 14:02:47 +01:00
|
|
|
#include <purple.h>
|
|
|
|
#include <algorithm>
|
|
|
|
|
2020-05-13 11:21:19 +02:00
|
|
|
static bool isCanonicalPhoneNumber(const char *s)
|
2020-05-04 17:32:33 +02:00
|
|
|
{
|
|
|
|
if (*s == '\0')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (const char *c = s; *c; c++)
|
|
|
|
if (!isdigit(*c))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isPhoneNumber(const char *s)
|
|
|
|
{
|
|
|
|
if (*s == '+') s++;
|
|
|
|
return isCanonicalPhoneNumber(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *getCanonicalPhoneNumber(const char *s)
|
|
|
|
{
|
|
|
|
if (*s == '+')
|
|
|
|
return s+1;
|
|
|
|
else
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId purpleBuddyNameToUserId(const char *s)
|
2020-05-13 11:21:19 +02:00
|
|
|
{
|
|
|
|
if (strncmp(s, "id", 2))
|
2020-10-04 15:17:04 +02:00
|
|
|
return UserId::invalid;
|
|
|
|
return stringToUserId(s+2);
|
2020-05-13 11:21:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 16:52:57 +02:00
|
|
|
SecretChatId purpleBuddyNameToSecretChatId(const char *s)
|
|
|
|
{
|
|
|
|
if (strncmp(s, "secret", 2))
|
|
|
|
return SecretChatId::invalid;
|
|
|
|
return stringToSecretChatId(s+6);
|
|
|
|
}
|
|
|
|
|
2020-05-04 17:32:33 +02:00
|
|
|
static bool isPhoneEqual(const std::string &n1, const std::string &n2)
|
|
|
|
{
|
|
|
|
const char *s1 = n1.c_str();
|
|
|
|
const char *s2 = n2.c_str();
|
|
|
|
if (*s1 == '+') s1++;
|
|
|
|
if (*s2 == '+') s2++;
|
|
|
|
return !strcmp(s1, s2);
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:13:06 +02:00
|
|
|
bool isPrivateChat(const td::td_api::chat &chat)
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
return getUserIdByPrivateChat(chat).valid();
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId getUserIdByPrivateChat(const td::td_api::chat &chat)
|
2020-05-20 15:13:06 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypePrivate::ID)) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat.type_);
|
2020-10-04 15:17:04 +02:00
|
|
|
return getUserId(privType);
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
return UserId::invalid;
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
|
|
|
|
2020-05-29 21:29:07 +02:00
|
|
|
bool isChatInContactList(const td::td_api::chat &chat, const td::td_api::user *privateChatUser)
|
|
|
|
{
|
|
|
|
return (chat.chat_list_ != nullptr) || (privateChatUser && privateChatUser->is_contact_);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
BasicGroupId getBasicGroupId(const td::td_api::chat &chat)
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeBasicGroup::ID))
|
2020-10-04 15:17:04 +02:00
|
|
|
return getBasicGroupId(static_cast<const td::td_api::chatTypeBasicGroup &>(*chat.type_));
|
2020-05-09 14:07:21 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
return BasicGroupId::invalid;
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
SupergroupId getSupergroupId(const td::td_api::chat &chat)
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeSupergroup::ID))
|
2020-10-04 15:17:04 +02:00
|
|
|
return getSupergroupId(static_cast<const td::td_api::chatTypeSupergroup &>(*chat.type_));
|
2020-05-09 14:07:21 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
return SupergroupId::invalid;
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 16:46:38 +02:00
|
|
|
SecretChatId getSecretChatId(const td::td_api::chat &chat)
|
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeSecret::ID))
|
|
|
|
return getSecretChatId(static_cast<const td::td_api::chatTypeSecret&>(*chat.type_));
|
|
|
|
|
|
|
|
return SecretChatId::invalid;
|
|
|
|
}
|
|
|
|
|
2020-05-10 14:24:15 +02:00
|
|
|
bool isGroupMember(const td::td_api::object_ptr<td::td_api::ChatMemberStatus> &status)
|
|
|
|
{
|
2020-05-22 14:02:48 +02:00
|
|
|
if (!status)
|
|
|
|
return false;
|
|
|
|
else if ((status->get_id() == td::td_api::chatMemberStatusLeft::ID) ||
|
|
|
|
(status->get_id() == td::td_api::chatMemberStatusBanned::ID))
|
|
|
|
return false;
|
|
|
|
else if (status->get_id() == td::td_api::chatMemberStatusRestricted::ID)
|
|
|
|
return static_cast<const td::td_api::chatMemberStatusRestricted &>(*status).is_member_;
|
|
|
|
else if (status->get_id() == td::td_api::chatMemberStatusCreator::ID)
|
|
|
|
return static_cast<const td::td_api::chatMemberStatusCreator &>(*status).is_member_;
|
|
|
|
else
|
|
|
|
return true;
|
2020-05-10 14:24:15 +02:00
|
|
|
}
|
|
|
|
|
2021-12-06 19:56:53 +01:00
|
|
|
bool isSameUser(const td::td_api::MessageSender &member1, const td::td_api::MessageSender &member2)
|
|
|
|
{
|
|
|
|
if ((member1.get_id() == td::td_api::messageSenderUser::ID) &&
|
|
|
|
(member2.get_id() == td::td_api::messageSenderUser::ID))
|
|
|
|
{
|
|
|
|
const td::td_api::messageSenderUser &user1 = static_cast<const td::td_api::messageSenderUser &>(member1);
|
|
|
|
const td::td_api::messageSenderUser &user2 = static_cast<const td::td_api::messageSenderUser &>(member2);
|
|
|
|
return (user1.user_id_ == user2.user_id_);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-29 19:39:22 +02:00
|
|
|
static std::string makeDisplayName(const td::td_api::user &user)
|
|
|
|
{
|
2020-07-25 12:49:38 +02:00
|
|
|
std::string result = makeBasicDisplayName(user);
|
2020-05-29 19:39:22 +02:00
|
|
|
|
|
|
|
// If some sneaky user sets their name equal to someone else's libpurple username, or to our
|
|
|
|
// phone number which is libpurple account name, make sure display name is different, because
|
|
|
|
// of how it is used for group chat members
|
2020-10-04 15:17:04 +02:00
|
|
|
if ((purpleBuddyNameToUserId(result.c_str()).valid()) || isPhoneNumber(result.c_str()))
|
2020-05-29 19:39:22 +02:00
|
|
|
result += ' ';
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-10-10 15:51:16 +02:00
|
|
|
auto PendingMessageQueue::getChatQueue(ChatId chatId) -> std::vector<ChatQueue>::iterator
|
|
|
|
{
|
|
|
|
return std::find_if(m_queues.begin(), m_queues.end(), [chatId](const ChatQueue &queue) {
|
|
|
|
return (queue.chatId == chatId);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-01-03 01:54:17 +01:00
|
|
|
PendingMessageQueue::Message &PendingMessageQueue::addMessage(ChatQueue &queue, MessageAction action)
|
|
|
|
{
|
|
|
|
if (action == MessageAction::Append) {
|
|
|
|
queue.messages.emplace_back();
|
|
|
|
return queue.messages.back();
|
|
|
|
} else {
|
|
|
|
queue.messages.emplace_front();
|
|
|
|
return queue.messages.front();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IncomingMessage &PendingMessageQueue::addPendingMessage(IncomingMessage &&message,
|
|
|
|
MessageAction action)
|
2020-10-10 15:51:16 +02:00
|
|
|
{
|
2020-10-18 18:33:41 +02:00
|
|
|
if (!message.message) return message;
|
2020-10-10 15:51:16 +02:00
|
|
|
|
2020-10-11 10:51:16 +02:00
|
|
|
ChatId chatId = getChatId(*message.message);
|
2020-10-10 15:51:16 +02:00
|
|
|
auto queueIt = getChatQueue(chatId);
|
|
|
|
ChatQueue *queue;
|
|
|
|
purple_debug_misc(config::pluginId,"MessageQueue: chat %" G_GINT64_FORMAT ": "
|
|
|
|
"adding pending message %" G_GINT64_FORMAT " (not ready)\n",
|
2020-10-11 10:51:16 +02:00
|
|
|
chatId.value(), message.message->id_);
|
2020-10-10 15:51:16 +02:00
|
|
|
|
|
|
|
if (queueIt != m_queues.end())
|
|
|
|
queue = &*queueIt;
|
|
|
|
else {
|
|
|
|
m_queues.emplace_back();
|
|
|
|
m_queues.back().chatId = chatId;
|
|
|
|
queue = &m_queues.back();
|
|
|
|
}
|
|
|
|
|
2021-01-03 01:54:17 +01:00
|
|
|
Message &newEntry = addMessage(*queue, action);
|
|
|
|
newEntry.ready = false;
|
|
|
|
newEntry.message = std::move(message);
|
|
|
|
return newEntry.message;
|
2020-10-10 15:51:16 +02:00
|
|
|
}
|
|
|
|
|
2021-01-02 21:54:31 +01:00
|
|
|
void PendingMessageQueue::extractReadyMessages(
|
|
|
|
std::vector<ChatQueue>::iterator pQueue,
|
|
|
|
std::vector<IncomingMessage> &readyMessages)
|
|
|
|
{
|
2021-01-03 01:54:17 +01:00
|
|
|
std::list<Message>::iterator pReady;
|
2021-01-02 21:54:31 +01:00
|
|
|
for (pReady = pQueue->messages.begin(); pReady != pQueue->messages.end(); ++pReady) {
|
|
|
|
if (!pReady->ready) break;
|
|
|
|
purple_debug_misc(config::pluginId,"MessageQueue: chat %" G_GINT64_FORMAT ": "
|
|
|
|
"showing message %" G_GINT64_FORMAT "\n",
|
|
|
|
pQueue->chatId.value(), getId(*pReady->message.message).value());
|
|
|
|
readyMessages.push_back(std::move(pReady->message));
|
|
|
|
}
|
|
|
|
|
|
|
|
pQueue->messages.erase(pQueue->messages.begin(), pReady);
|
|
|
|
if (pQueue->messages.empty()) {
|
|
|
|
m_queues.erase(pQueue);
|
|
|
|
pQueue = m_queues.end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-10 15:51:16 +02:00
|
|
|
void PendingMessageQueue::setMessageReady(ChatId chatId, MessageId messageId,
|
|
|
|
std::vector<IncomingMessage> &readyMessages)
|
|
|
|
{
|
|
|
|
readyMessages.clear();
|
|
|
|
|
2021-01-02 21:54:31 +01:00
|
|
|
auto pQueue = getChatQueue(chatId);
|
|
|
|
if (pQueue == m_queues.end()) return;
|
2020-10-10 15:51:16 +02:00
|
|
|
|
|
|
|
purple_debug_misc(config::pluginId,"MessageQueue: chat %" G_GINT64_FORMAT ": "
|
|
|
|
"message %" G_GINT64_FORMAT " now ready\n",
|
|
|
|
chatId.value(), messageId.value());
|
|
|
|
|
2021-01-02 21:54:31 +01:00
|
|
|
auto it = std::find_if(pQueue->messages.begin(), pQueue->messages.end(), [messageId](const Message &m) {
|
2020-10-10 15:51:16 +02:00
|
|
|
return (getId(*m.message.message) == messageId);
|
|
|
|
});
|
2021-01-02 21:54:31 +01:00
|
|
|
if (it == pQueue->messages.end()) return;
|
2020-10-10 15:51:16 +02:00
|
|
|
|
|
|
|
it->ready = true;
|
2021-01-02 21:54:31 +01:00
|
|
|
if (pQueue->ready && (it == pQueue->messages.begin()))
|
|
|
|
extractReadyMessages(pQueue, readyMessages);
|
2020-10-10 15:51:16 +02:00
|
|
|
}
|
|
|
|
|
2021-01-03 01:54:17 +01:00
|
|
|
IncomingMessage PendingMessageQueue::addReadyMessage(IncomingMessage &&message,
|
|
|
|
MessageAction action)
|
2020-10-10 15:51:16 +02:00
|
|
|
{
|
2020-10-11 10:51:16 +02:00
|
|
|
if (!message.message) return IncomingMessage();
|
2020-10-10 15:51:16 +02:00
|
|
|
|
2020-10-11 10:51:16 +02:00
|
|
|
ChatId chatId = getChatId(*message.message);
|
2020-10-10 15:51:16 +02:00
|
|
|
auto queueIt = getChatQueue(chatId);
|
|
|
|
if (queueIt == m_queues.end())
|
2020-10-11 10:51:16 +02:00
|
|
|
return std::move(message);
|
2020-10-10 15:51:16 +02:00
|
|
|
|
|
|
|
purple_debug_misc(config::pluginId,"MessageQueue: chat %" G_GINT64_FORMAT ": "
|
|
|
|
"adding pending message %" G_GINT64_FORMAT " (ready)\n",
|
2020-10-11 10:51:16 +02:00
|
|
|
chatId.value(), message.message->id_);
|
2020-10-10 15:51:16 +02:00
|
|
|
|
2021-01-03 01:54:17 +01:00
|
|
|
Message &newEntry = addMessage(*queueIt, action);
|
|
|
|
newEntry.ready = true;
|
|
|
|
newEntry.message = std::move(message);
|
2020-10-10 15:51:16 +02:00
|
|
|
|
2020-10-11 10:51:16 +02:00
|
|
|
return IncomingMessage();
|
2020-10-10 15:51:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
IncomingMessage *PendingMessageQueue::findPendingMessage(ChatId chatId, MessageId messageId)
|
|
|
|
{
|
|
|
|
auto queueIt = getChatQueue(chatId);
|
|
|
|
if (queueIt == m_queues.end()) return nullptr;
|
|
|
|
ChatQueue *queue = &*queueIt;
|
|
|
|
|
|
|
|
auto it = std::find_if(queue->messages.begin(), queue->messages.end(), [messageId](const Message &m) {
|
|
|
|
return (getId(*m.message.message) == messageId);
|
|
|
|
});
|
|
|
|
return (it != queue->messages.end()) ? &it->message : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PendingMessageQueue::flush(std::vector<IncomingMessage> &messages)
|
|
|
|
{
|
|
|
|
messages.clear();
|
|
|
|
for (ChatQueue &queue: m_queues)
|
|
|
|
for (Message &message: queue.messages)
|
|
|
|
messages.push_back(std::move(message.message));
|
|
|
|
m_queues.clear();
|
|
|
|
}
|
|
|
|
|
2021-01-02 21:54:31 +01:00
|
|
|
void PendingMessageQueue::setChatNotReady(ChatId chatId)
|
|
|
|
{
|
|
|
|
auto pQueue = getChatQueue(chatId);
|
|
|
|
if (pQueue != m_queues.end())
|
|
|
|
pQueue->ready = false;
|
|
|
|
else {
|
|
|
|
m_queues.emplace_back();
|
|
|
|
m_queues.back().chatId = chatId;
|
|
|
|
m_queues.back().ready = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PendingMessageQueue::setChatReady(ChatId chatId, std::vector<IncomingMessage>& readyMessages)
|
|
|
|
{
|
|
|
|
readyMessages.clear();
|
|
|
|
auto pQueue = getChatQueue(chatId);
|
|
|
|
if (pQueue == m_queues.end()) return;
|
|
|
|
|
|
|
|
pQueue->ready = true;
|
|
|
|
extractReadyMessages(pQueue, readyMessages);
|
|
|
|
}
|
|
|
|
|
2021-01-02 22:57:20 +01:00
|
|
|
bool PendingMessageQueue::isChatReady(ChatId chatId)
|
|
|
|
{
|
|
|
|
auto pQueue = getChatQueue(chatId);
|
|
|
|
if (pQueue != m_queues.end())
|
|
|
|
return pQueue->ready;
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-05-29 21:29:07 +02:00
|
|
|
void TdAccountData::updateUser(TdUserPtr userPtr)
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
2020-05-29 21:29:07 +02:00
|
|
|
const td::td_api::user *user = userPtr.get();
|
2020-05-29 19:39:22 +02:00
|
|
|
if (user) {
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId userId = getId(*user);
|
2020-05-29 21:29:07 +02:00
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
|
|
|
|
if (it == m_userInfo.end()) {
|
|
|
|
auto ret = m_userInfo.emplace(std::make_pair(userId, UserInfo()));
|
|
|
|
it = ret.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
UserInfo &entry = it->second;
|
|
|
|
entry.user = std::move(userPtr);
|
2020-06-07 01:14:06 +02:00
|
|
|
entry.displayName = makeDisplayName(*user);
|
|
|
|
for (unsigned n = 0; n != UINT32_MAX; n++) {
|
|
|
|
std::string displayName = entry.displayName;
|
|
|
|
if (n != 0) {
|
|
|
|
displayName += " #";
|
|
|
|
displayName += std::to_string(n);
|
|
|
|
}
|
2020-05-29 21:29:07 +02:00
|
|
|
|
2020-06-07 01:14:06 +02:00
|
|
|
std::vector<const td::td_api::user *> existingUsers;
|
|
|
|
getUsersByDisplayName(displayName.c_str(), existingUsers);
|
|
|
|
if (std::none_of(existingUsers.begin(), existingUsers.end(),
|
|
|
|
[user](const td::td_api::user *otherUser) {
|
|
|
|
return (otherUser != user);
|
|
|
|
}))
|
|
|
|
{
|
|
|
|
entry.displayName = std::move(displayName);
|
|
|
|
break;
|
2020-05-29 21:29:07 +02:00
|
|
|
}
|
2020-05-29 19:39:22 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
2020-05-07 21:15:32 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setUserStatus(UserId userId, td::td_api::object_ptr<td::td_api::UserStatus> status)
|
2020-05-16 21:08:05 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end())
|
2020-05-29 19:39:22 +02:00
|
|
|
it->second.user->status_ = std::move(status);
|
2020-05-16 21:08:05 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSmallProfilePhoto(UserId userId, td::td_api::object_ptr<td::td_api::file> photo)
|
2020-06-04 22:57:01 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end()) {
|
|
|
|
td::td_api::user &user = *it->second.user;
|
|
|
|
if (user.profile_photo_)
|
|
|
|
user.profile_photo_->small_ = std::move(photo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-09 14:07:21 +02:00
|
|
|
void TdAccountData::updateBasicGroup(TdGroupPtr group)
|
|
|
|
{
|
|
|
|
if (group)
|
2020-10-04 15:17:04 +02:00
|
|
|
m_groups[getId(*group)].group = std::move(group);
|
2020-05-11 19:35:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setBasicGroupInfoRequested(BasicGroupId groupId)
|
2020-05-20 21:31:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::isBasicGroupInfoRequested(BasicGroupId groupId)
|
2020-05-20 21:31:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateBasicGroupInfo(BasicGroupId groupId, TdGroupInfoPtr groupInfo)
|
2020-05-11 19:35:27 +02:00
|
|
|
{
|
|
|
|
if (groupInfo)
|
|
|
|
m_groups[groupId].fullInfo = std::move(groupInfo);
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
2020-02-23 14:02:47 +01:00
|
|
|
|
2020-05-09 14:07:21 +02:00
|
|
|
void TdAccountData::updateSupergroup(TdSupergroupPtr group)
|
|
|
|
{
|
|
|
|
if (group)
|
2020-10-04 15:17:04 +02:00
|
|
|
m_supergroups[getId(*group)].group = std::move(group);
|
2020-06-01 11:12:26 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setSupergroupInfoRequested(SupergroupId groupId)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::isSupergroupInfoRequested(SupergroupId groupId)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSupergroupInfo(SupergroupId groupId, TdSupergroupInfoPtr groupInfo)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
if (groupInfo)
|
|
|
|
m_supergroups[groupId].fullInfo = std::move(groupInfo);
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSupergroupMembers(SupergroupId groupId, TdChatMembersPtr members)
|
2020-07-05 15:01:24 +02:00
|
|
|
{
|
|
|
|
if (members)
|
|
|
|
m_supergroups[groupId].members = std::move(members);
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:35:31 +02:00
|
|
|
void TdAccountData::addChat(TdChatPtr chat)
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
2020-05-08 19:50:55 +02:00
|
|
|
if (!chat)
|
2020-02-23 14:02:47 +01:00
|
|
|
return;
|
|
|
|
|
2020-05-02 12:35:31 +02:00
|
|
|
if (chat->type_->get_id() == td::td_api::chatTypePrivate::ID) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat->type_);
|
|
|
|
auto pContact = std::find(m_contactUserIdsNoChat.begin(), m_contactUserIdsNoChat.end(),
|
2020-10-04 15:17:04 +02:00
|
|
|
getUserId(privType));
|
2020-05-02 12:35:31 +02:00
|
|
|
if (pContact != m_contactUserIdsNoChat.end()) {
|
2021-12-06 19:56:53 +01:00
|
|
|
purpleDebug("Private chat (id {}) now known for user {}", {
|
|
|
|
std::to_string(chat->id_), std::to_string(privType.user_id_)
|
|
|
|
});
|
2020-05-02 12:35:31 +02:00
|
|
|
m_contactUserIdsNoChat.erase(pContact);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
auto it = m_chatInfo.find(getId(*chat));
|
2020-05-09 18:58:04 +02:00
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat = std::move(chat);
|
|
|
|
else {
|
2020-10-04 15:17:04 +02:00
|
|
|
auto entry = m_chatInfo.emplace(getId(*chat), ChatInfo());
|
2020-05-09 18:58:04 +02:00
|
|
|
entry.first->second.chat = std::move(chat);
|
|
|
|
entry.first->second.purpleId = ++m_lastChatPurpleId;
|
|
|
|
}
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatChatList(ChatId chatId, td::td_api::object_ptr<td::td_api::ChatList> list)
|
2020-05-19 16:36:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->chat_list_ = std::move(list);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatTitle(ChatId chatId, const std::string &title)
|
2020-05-20 13:33:47 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->title_ = title;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSmallChatPhoto(ChatId chatId, td::td_api::object_ptr<td::td_api::file> photo)
|
2020-06-04 22:57:01 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end()) {
|
|
|
|
td::td_api::chat &chat = *it->second.chat;
|
|
|
|
if (chat.photo_)
|
|
|
|
chat.photo_->small_ = std::move(photo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatOrder(ChatId chatId, int64_t order)
|
2020-06-05 23:20:44 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->order_ = order;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setContacts(const td::td_api::users &users)
|
2020-05-02 12:35:31 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
for (unsigned i = 0; i < users.user_ids_.size(); i++) {
|
|
|
|
UserId userId = getUserId(users, i);
|
2020-05-02 12:35:31 +02:00
|
|
|
if (getPrivateChatByUserId(userId) == nullptr) {
|
2021-12-06 19:56:53 +01:00
|
|
|
purpleDebug("Private chat not yet known for user {}", userId.value());
|
2020-05-02 12:35:31 +02:00
|
|
|
m_contactUserIdsNoChat.push_back(userId);
|
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
}
|
2020-05-02 12:35:31 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::getContactsWithNoChat(std::vector<UserId> &userIds)
|
2020-05-02 12:35:31 +02:00
|
|
|
{
|
|
|
|
userIds = m_contactUserIdsNoChat;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getChat(ChatId chatId) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
auto pChatInfo = m_chatInfo.find(chatId);
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-09 18:58:04 +02:00
|
|
|
return pChatInfo->second.chat.get();
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
int TdAccountData::getPurpleChatId(ChatId tdChatId)
|
2020-05-09 18:58:04 +02:00
|
|
|
{
|
|
|
|
auto pChatInfo = m_chatInfo.find(tdChatId);
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return pChatInfo->second.purpleId;
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-05-10 14:24:15 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getChatByPurpleId(int32_t purpleChatId) const
|
|
|
|
{
|
|
|
|
auto pChatInfo = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
|
|
|
[purpleChatId](const ChatMap::value_type &entry) {
|
|
|
|
return (entry.second.purpleId == purpleChatId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (pChatInfo != m_chatInfo.end())
|
|
|
|
return pChatInfo->second.chat.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
static bool isPrivateChat(const td::td_api::chat &chat, UserId userId)
|
2020-02-27 21:49:02 +01:00
|
|
|
{
|
|
|
|
if (chat.type_->get_id() == td::td_api::chatTypePrivate::ID) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat.type_);
|
2020-10-04 15:17:04 +02:00
|
|
|
return (getUserId(privType) == userId);
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getPrivateChatByUserId(UserId userId) const
|
2020-02-27 21:49:02 +01:00
|
|
|
{
|
|
|
|
auto pChatInfo = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[userId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return isPrivateChat(*entry.second.chat, userId);
|
2020-02-27 21:49:02 +01:00
|
|
|
});
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-09 18:58:04 +02:00
|
|
|
return pChatInfo->second.chat.get();
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::user *TdAccountData::getUser(UserId userId) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
auto pUser = m_userInfo.find(userId);
|
|
|
|
if (pUser == m_userInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-29 19:39:22 +02:00
|
|
|
return pUser->second.user.get();
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-02-27 21:49:02 +01:00
|
|
|
const td::td_api::user *TdAccountData::getUserByPhone(const char *phoneNumber) const
|
|
|
|
{
|
|
|
|
auto pUser = std::find_if(m_userInfo.begin(), m_userInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[phoneNumber](const UserMap::value_type &entry) {
|
2020-05-29 19:39:22 +02:00
|
|
|
return isPhoneEqual(entry.second.user->phone_number_, phoneNumber);
|
2020-02-27 21:49:02 +01:00
|
|
|
});
|
|
|
|
if (pUser == m_userInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-29 19:39:22 +02:00
|
|
|
return pUser->second.user.get();
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
|
2020-05-04 14:08:57 +02:00
|
|
|
const td::td_api::user *TdAccountData::getUserByPrivateChat(const td::td_api::chat &chat)
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId userId = getUserIdByPrivateChat(chat);
|
|
|
|
if (userId.valid())
|
2020-05-20 15:13:06 +02:00
|
|
|
return getUser(userId);
|
2020-05-04 14:08:57 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-29 19:39:22 +02:00
|
|
|
std::string TdAccountData::getDisplayName(const td::td_api::user &user) const
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
return getDisplayName(getId(user));
|
2020-05-29 19:39:22 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
std::string TdAccountData::getDisplayName(UserId userId) const
|
2020-05-29 19:39:22 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end())
|
|
|
|
return it->second.displayName;
|
|
|
|
else
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:38:58 +02:00
|
|
|
void TdAccountData::getUsersByDisplayName(const char *displayName,
|
2020-05-29 21:29:07 +02:00
|
|
|
std::vector<const td::td_api::user*> &users)
|
2020-05-16 20:38:58 +02:00
|
|
|
{
|
|
|
|
users.clear();
|
|
|
|
if (!displayName || (*displayName == '\0'))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (const UserMap::value_type &entry: m_userInfo)
|
2020-05-29 19:39:22 +02:00
|
|
|
if (entry.second.displayName == displayName)
|
|
|
|
users.push_back(entry.second.user.get());
|
2020-05-16 20:38:58 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::basicGroup *TdAccountData::getBasicGroup(BasicGroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
2020-05-11 19:35:27 +02:00
|
|
|
return it->second.group.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::basicGroupFullInfo *TdAccountData::getBasicGroupInfo(BasicGroupId groupId) const
|
2020-05-11 19:35:27 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
return it->second.fullInfo.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::supergroup *TdAccountData::getSupergroup(SupergroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
2020-06-01 11:12:26 +02:00
|
|
|
return it->second.group.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::supergroupFullInfo *TdAccountData::getSupergroupInfo(SupergroupId groupId) const
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.fullInfo.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chatMembers *TdAccountData::getSupergroupMembers(SupergroupId groupId) const
|
2020-07-05 15:01:24 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.members.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getBasicGroupChatByGroup(BasicGroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
if (!groupId.valid())
|
2020-05-09 14:07:21 +02:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto it = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[groupId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return (getBasicGroupId(*entry.second.chat) == groupId);
|
2020-05-09 14:07:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_chatInfo.end())
|
2020-05-09 18:58:04 +02:00
|
|
|
return it->second.chat.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getSupergroupChatByGroup(SupergroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
if (!groupId.valid())
|
2020-05-09 14:07:21 +02:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto it = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[groupId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return (getSupergroupId(*entry.second.chat) == groupId);
|
2020-05-09 14:07:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_chatInfo.end())
|
2020-05-09 18:58:04 +02:00
|
|
|
return it->second.chat.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-06-11 00:04:29 +02:00
|
|
|
bool TdAccountData::isGroupChatWithMembership(const td::td_api::chat &chat) const
|
2020-05-10 14:24:15 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
BasicGroupId groupId = getBasicGroupId(chat);
|
|
|
|
if (groupId.valid()) {
|
2020-05-10 14:24:15 +02:00
|
|
|
const td::td_api::basicGroup *group = getBasicGroup(groupId);
|
|
|
|
return (group && isGroupMember(group->status_));
|
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
SupergroupId supergroupId = getSupergroupId(chat);
|
|
|
|
if (supergroupId.valid()) {
|
|
|
|
const td::td_api::supergroup *group = getSupergroup(supergroupId);
|
2020-05-10 14:24:15 +02:00
|
|
|
return (group && isGroupMember(group->status_));
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 16:46:38 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getChatBySecretChat(SecretChatId secretChatId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
|
|
|
[secretChatId](const ChatMap::value_type &entry) {
|
|
|
|
return (getSecretChatId(*entry.second.chat) == secretChatId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
return it->second.chat.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-20 21:31:58 +02:00
|
|
|
void TdAccountData::getChats(std::vector<const td::td_api::chat *> &chats) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
chats.clear();
|
2020-05-20 21:31:58 +02:00
|
|
|
for (const ChatMap::value_type &item: m_chatInfo)
|
|
|
|
chats.push_back(item.second.chat.get());
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::deleteChat(ChatId id)
|
2020-05-21 14:51:52 +02:00
|
|
|
{
|
|
|
|
m_chatInfo.erase(id);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::getSmallestOrderChat(const td::td_api::ChatList &list, ChatId &chatId, int64_t &order)
|
2020-06-05 23:20:44 +02:00
|
|
|
{
|
|
|
|
int64_t minOrder = INT64_MAX;
|
2020-10-04 15:17:04 +02:00
|
|
|
ChatId id = ChatId::invalid;
|
2020-06-05 23:20:44 +02:00
|
|
|
for (const ChatMap::value_type &entry: m_chatInfo) {
|
|
|
|
int64_t order = entry.second.chat->order_;
|
|
|
|
if (entry.second.chat->chat_list_ && (entry.second.chat->chat_list_->get_id() == list.get_id()) &&
|
|
|
|
(order < minOrder))
|
|
|
|
{
|
|
|
|
minOrder = order;
|
|
|
|
id = entry.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
chatId = id;
|
|
|
|
order = minOrder;
|
|
|
|
}
|
|
|
|
|
2020-10-09 23:40:34 +02:00
|
|
|
void TdAccountData::addExpectedChat(ChatId id)
|
|
|
|
{
|
|
|
|
if (!isExpectedChat(id))
|
|
|
|
m_expectedChats.push_back(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TdAccountData::isExpectedChat(ChatId chatId)
|
|
|
|
{
|
|
|
|
return (std::find(m_expectedChats.begin(), m_expectedChats.end(), chatId) != m_expectedChats.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::removeExpectedChat(ChatId id)
|
|
|
|
{
|
|
|
|
auto expIt = std::find(m_expectedChats.begin(), m_expectedChats.end(), id);
|
|
|
|
if (expIt != m_expectedChats.end())
|
|
|
|
m_expectedChats.erase(expIt);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-11 19:35:27 +02:00
|
|
|
std::unique_ptr<PendingRequest> TdAccountData::getPendingRequestImpl(uint64_t requestId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[requestId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
return (req->requestId == requestId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end()) {
|
|
|
|
auto result = std::move(*it);
|
|
|
|
m_requests.erase(it);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2020-05-13 12:31:03 +02:00
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
PendingRequest *TdAccountData::findPendingRequestImpl(uint64_t requestId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[requestId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
return (req->requestId == requestId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return it->get();
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const ContactRequest *TdAccountData::findContactRequest(UserId userId)
|
2020-05-13 12:31:03 +02:00
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[userId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
const ContactRequest *contactReq = dynamic_cast<const ContactRequest *>(req.get());
|
|
|
|
return (contactReq && (contactReq->userId == userId));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return static_cast<const ContactRequest *>(it->get());
|
|
|
|
return nullptr;
|
|
|
|
}
|
2020-05-16 00:16:06 +02:00
|
|
|
|
2020-06-04 01:28:49 +02:00
|
|
|
DownloadRequest* TdAccountData::findDownloadRequest(int32_t fileId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[fileId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
DownloadRequest *downloadReq = dynamic_cast<DownloadRequest *>(req.get());
|
|
|
|
return (downloadReq && (downloadReq->fileId == fileId));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return static_cast<DownloadRequest *>(it->get());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-01-09 12:17:38 +01:00
|
|
|
void TdAccountData::extractFileTransferRequests(std::vector<PurpleXfer *> &transfers)
|
|
|
|
{
|
|
|
|
transfers.clear();
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < m_requests.size(); ) {
|
|
|
|
UploadRequest *uploadReq = dynamic_cast<UploadRequest *>(m_requests[i].get());
|
|
|
|
NewPrivateChatForMessage *newChatReq = dynamic_cast<NewPrivateChatForMessage *>(m_requests[i].get());
|
|
|
|
PurpleXfer *xfer = NULL;
|
|
|
|
if (uploadReq)
|
|
|
|
xfer = uploadReq->xfer;
|
|
|
|
else if (newChatReq)
|
|
|
|
xfer = newChatReq->fileUpload;
|
|
|
|
|
|
|
|
if (xfer) {
|
|
|
|
transfers.push_back(xfer);
|
|
|
|
m_requests.erase(m_requests.begin() + i);
|
|
|
|
} else
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-16 00:16:06 +02:00
|
|
|
void TdAccountData::addTempFileUpload(int64_t messageId, const std::string &path)
|
|
|
|
{
|
|
|
|
m_sentMessages.emplace_back();
|
|
|
|
m_sentMessages.back().messageId = messageId;
|
|
|
|
m_sentMessages.back().tempFile = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TdAccountData::extractTempFileUpload(int64_t messageId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_sentMessages.begin(), m_sentMessages.end(),
|
|
|
|
[messageId](const SendMessageInfo &item) {
|
|
|
|
return (item.messageId == messageId);
|
|
|
|
});
|
|
|
|
|
|
|
|
std::string result;
|
|
|
|
if (it != m_sentMessages.end()) {
|
|
|
|
result = it->tempFile;
|
|
|
|
m_sentMessages.erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2020-05-16 13:38:00 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::addFileTransfer(int32_t fileId, PurpleXfer *xfer, ChatId chatId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
if (std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) {
|
|
|
|
return (upload.fileId == fileId);
|
|
|
|
}) == m_fileTransfers.end()) {
|
|
|
|
m_fileTransfers.emplace_back();
|
|
|
|
m_fileTransfers.back().fileId = fileId;
|
|
|
|
m_fileTransfers.back().xfer = xfer;
|
|
|
|
m_fileTransfers.back().chatId = chatId;
|
2020-05-28 21:29:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::getFileTransfer(int32_t fileId, PurpleXfer *&xfer, ChatId &chatId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) { return (upload.fileId == fileId); });
|
|
|
|
if (it != m_fileTransfers.end()) {
|
2020-05-28 21:29:58 +02:00
|
|
|
xfer = it->xfer;
|
|
|
|
chatId = it->chatId;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
bool TdAccountData::getFileIdForTransfer(PurpleXfer *xfer, int &fileId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[xfer](const FileTransferInfo &upload) { return (upload.xfer == xfer); });
|
|
|
|
if (it != m_fileTransfers.end()) {
|
2020-05-28 21:29:58 +02:00
|
|
|
fileId = it->fileId;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
void TdAccountData::removeFileTransfer(int32_t fileId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) { return (upload.fileId == fileId); });
|
|
|
|
if (it != m_fileTransfers.end())
|
|
|
|
m_fileTransfers.erase(it);
|
2020-05-28 21:29:58 +02:00
|
|
|
}
|
2020-05-31 15:55:28 +02:00
|
|
|
|
2021-01-09 12:17:38 +01:00
|
|
|
void TdAccountData::removeAllFileTransfers(std::vector<PurpleXfer *>& transfers)
|
|
|
|
{
|
|
|
|
transfers.resize(m_fileTransfers.size());
|
|
|
|
for (size_t i = 0; i < m_fileTransfers.size(); i++)
|
|
|
|
transfers[i] = m_fileTransfers[i].xfer;
|
|
|
|
m_fileTransfers.clear();
|
|
|
|
}
|
|
|
|
|
2020-05-31 15:55:28 +02:00
|
|
|
void TdAccountData::addSecretChat(td::td_api::object_ptr<td::td_api::secretChat> secretChat)
|
|
|
|
{
|
|
|
|
if (secretChat)
|
2020-10-04 16:46:38 +02:00
|
|
|
m_secretChats[getId(*secretChat)] = std::move(secretChat);
|
2020-05-31 15:55:28 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 16:46:38 +02:00
|
|
|
const td::td_api::secretChat *TdAccountData::getSecretChat(SecretChatId id)
|
2020-05-31 15:55:28 +02:00
|
|
|
{
|
2020-10-04 16:46:38 +02:00
|
|
|
auto it = m_secretChats.find(id);
|
|
|
|
return (it != m_secretChats.end()) ? it->second.get() : nullptr;
|
2020-05-31 15:55:28 +02:00
|
|
|
}
|
2020-06-06 22:33:56 +02:00
|
|
|
|
2020-10-05 23:29:20 +02:00
|
|
|
void TdAccountData::deleteSecretChat(SecretChatId id)
|
|
|
|
{
|
|
|
|
m_secretChats.erase(id);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
std::vector<std::pair<BasicGroupId, const td::td_api::basicGroupFullInfo *>>
|
|
|
|
TdAccountData::getBasicGroupsWithMember(UserId userId)
|
2020-06-06 22:33:56 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
std::vector<std::pair<BasicGroupId, const td::td_api::basicGroupFullInfo *>> result;
|
2020-06-06 22:33:56 +02:00
|
|
|
|
|
|
|
for (const auto &item: m_groups)
|
|
|
|
if (item.second.fullInfo) {
|
|
|
|
auto &members = item.second.fullInfo->members_;
|
|
|
|
if (std::any_of(members.begin(), members.end(),
|
|
|
|
[userId](const td::td_api::object_ptr<td::td_api::chatMember> &member) {
|
2020-10-04 15:17:04 +02:00
|
|
|
return (member && (getUserId(*member) == userId));
|
2020-06-06 22:33:56 +02:00
|
|
|
}))
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
result.push_back(std::make_pair(getId(*item.second.group), item.second.fullInfo.get()));
|
2020-06-06 22:33:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2020-07-26 23:44:51 +02:00
|
|
|
|
|
|
|
bool TdAccountData::hasActiveCall()
|
|
|
|
{
|
|
|
|
return (m_callData != nullptr);
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:56:42 +02:00
|
|
|
void TdAccountData::setActiveCall(int32_t callId)
|
2020-07-26 23:44:51 +02:00
|
|
|
{
|
2020-07-27 16:56:42 +02:00
|
|
|
if (!m_callData) {
|
2020-07-26 23:44:51 +02:00
|
|
|
m_callData = std::make_unique<tgvoip::VoIPController>();
|
2020-07-27 16:56:42 +02:00
|
|
|
m_callId = callId;
|
|
|
|
}
|
2020-07-26 23:44:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
tgvoip::VoIPController *TdAccountData::getCallData()
|
|
|
|
{
|
|
|
|
return m_callData.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::removeActiveCall()
|
|
|
|
{
|
|
|
|
m_callData.reset();
|
2020-07-27 16:56:42 +02:00
|
|
|
m_callId = 0;
|
2020-07-26 23:44:51 +02:00
|
|
|
}
|
2020-12-31 17:10:52 +01:00
|
|
|
|
|
|
|
void TdAccountData::addPendingReadReceipt(ChatId chatId, MessageId messageId)
|
|
|
|
{
|
2021-01-01 14:47:21 +01:00
|
|
|
auto pChatReceipts = std::find_if(m_pendingReadReceipts.begin(), m_pendingReadReceipts.end(),
|
|
|
|
[chatId](const std::vector<ReadReceipt> &receipts) {
|
|
|
|
return (!receipts.empty() && (receipts[0].chatId == chatId));
|
|
|
|
});
|
|
|
|
if (pChatReceipts != m_pendingReadReceipts.end())
|
|
|
|
pChatReceipts->push_back(ReadReceipt{chatId, messageId});
|
|
|
|
else {
|
|
|
|
m_pendingReadReceipts.emplace_back();
|
|
|
|
m_pendingReadReceipts.back().push_back(ReadReceipt{chatId, messageId});
|
|
|
|
}
|
2020-12-31 17:10:52 +01:00
|
|
|
}
|
|
|
|
|
2021-01-01 14:47:21 +01:00
|
|
|
void TdAccountData::extractPendingReadReceipts(ChatId chatId, std::vector<ReadReceipt>& receipts)
|
2020-12-31 17:10:52 +01:00
|
|
|
{
|
2021-01-01 14:47:21 +01:00
|
|
|
auto pChatReceipts = std::find_if(m_pendingReadReceipts.begin(), m_pendingReadReceipts.end(),
|
|
|
|
[chatId](const std::vector<ReadReceipt> &receipts) {
|
|
|
|
return (!receipts.empty() && (receipts[0].chatId == chatId));
|
|
|
|
});
|
|
|
|
if (pChatReceipts != m_pendingReadReceipts.end()) {
|
|
|
|
receipts = std::move(*pChatReceipts);
|
|
|
|
m_pendingReadReceipts.erase(pChatReceipts);
|
|
|
|
} else
|
|
|
|
receipts.clear();
|
2020-12-31 17:10:52 +01:00
|
|
|
}
|