mirror of
https://github.com/ars3niy/tdlib-purple
synced 2025-08-22 01:49:29 +00:00
Send read receipts only when conversation has focus
This commit is contained in:
parent
ec01fa2b5f
commit
c8b55eb887
@ -878,10 +878,27 @@ void TdAccountData::removeActiveCall()
|
||||
|
||||
void TdAccountData::addPendingReadReceipt(ChatId chatId, MessageId messageId)
|
||||
{
|
||||
m_pendingReadReceipts.push_back(ReadReceipt{chatId, messageId});
|
||||
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});
|
||||
}
|
||||
}
|
||||
|
||||
void TdAccountData::extractPendingReadReceipts(std::vector<ReadReceipt>& receipts)
|
||||
void TdAccountData::extractPendingReadReceipts(ChatId chatId, std::vector<ReadReceipt>& receipts)
|
||||
{
|
||||
receipts = std::move(m_pendingReadReceipts);
|
||||
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();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "buildopt.h"
|
||||
#include "identifiers.h"
|
||||
#include "transceiver.h"
|
||||
#include <td/telegram/td_api.h>
|
||||
|
||||
#include <map>
|
||||
@ -286,8 +287,10 @@ public:
|
||||
unsigned maxMessageLength = 0;
|
||||
} options;
|
||||
|
||||
PurpleAccount *const purpleAccount;
|
||||
TdAccountData(PurpleAccount *purpleAccount) : purpleAccount(purpleAccount) {}
|
||||
PurpleAccount *const purpleAccount;
|
||||
TdTransceiver &transceiver;
|
||||
TdAccountData(PurpleAccount *purpleAccount, TdTransceiver &transceiver)
|
||||
: purpleAccount(purpleAccount), transceiver(transceiver) {}
|
||||
|
||||
void updateUser(TdUserPtr user);
|
||||
void setUserStatus(UserId UserId, td::td_api::object_ptr<td::td_api::UserStatus> status);
|
||||
@ -388,7 +391,7 @@ public:
|
||||
PendingMessageQueue pendingMessages;
|
||||
|
||||
void addPendingReadReceipt(ChatId chatId, MessageId messageId);
|
||||
void extractPendingReadReceipts(std::vector<ReadReceipt> &receipts);
|
||||
void extractPendingReadReceipts(ChatId chatId, std::vector<ReadReceipt> &receipts);
|
||||
private:
|
||||
TdAccountData(const TdAccountData &other) = delete;
|
||||
TdAccountData &operator=(const TdAccountData &other) = delete;
|
||||
@ -463,8 +466,8 @@ private:
|
||||
std::unique_ptr<PendingRequest> getPendingRequestImpl(uint64_t requestId);
|
||||
PendingRequest * findPendingRequestImpl(uint64_t requestId);
|
||||
|
||||
// Read receipts not sent immediately due to away status
|
||||
std::vector<ReadReceipt> m_pendingReadReceipts;
|
||||
// Read receipts not sent immediately due to away status (grouped per chat)
|
||||
std::vector<std::vector<ReadReceipt>> m_pendingReadReceipts;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
1
call.h
1
call.h
@ -1,7 +1,6 @@
|
||||
#ifndef _CALL_H
|
||||
#define _CALL_H
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "account-data.h"
|
||||
|
||||
bool initiateCall(int32_t userId, TdAccountData &account, TdTransceiver &transceiver);
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _CLIENT_UTILS_H
|
||||
|
||||
#include "account-data.h"
|
||||
#include "transceiver.h"
|
||||
#include <purple.h>
|
||||
#include <thread>
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _FILE_TRANSFER_H
|
||||
|
||||
#include "account-data.h"
|
||||
#include "transceiver.h"
|
||||
|
||||
enum {
|
||||
FILE_DOWNLOAD_PRIORITY = 1,
|
||||
|
@ -42,6 +42,39 @@ void sendConversationReadReceipts(TdAccountData &account, PurpleConversation *co
|
||||
{
|
||||
if (!conversationHasFocus(conv))
|
||||
return;
|
||||
ChatId chatId;
|
||||
PurpleConversationType convType = purple_conversation_get_type(conv);
|
||||
const char *convName = purple_conversation_get_name(conv);
|
||||
|
||||
if (convType == PURPLE_CONV_TYPE_IM) {
|
||||
UserId privateChatUserId = purpleBuddyNameToUserId(convName);
|
||||
SecretChatId secretChatId = purpleBuddyNameToSecretChatId(convName);
|
||||
const td::td_api::chat *tdlibChat = nullptr;
|
||||
|
||||
if (privateChatUserId.valid())
|
||||
tdlibChat = account.getPrivateChatByUserId(privateChatUserId);
|
||||
else if (secretChatId.valid())
|
||||
tdlibChat = account.getChatBySecretChat(secretChatId);
|
||||
|
||||
if (tdlibChat)
|
||||
chatId = getId(*tdlibChat);
|
||||
} else if (convType == PURPLE_CONV_TYPE_CHAT)
|
||||
chatId = getTdlibChatId(convName);
|
||||
|
||||
std::vector<ReadReceipt> receipts;
|
||||
account.extractPendingReadReceipts(chatId, receipts);
|
||||
|
||||
if (!receipts.empty()) {
|
||||
purple_debug_misc(config::pluginId, "Sending %zu read receipts for chat %" G_GINT64_FORMAT "\n",
|
||||
receipts.size(), chatId.value());
|
||||
td::td_api::object_ptr<td::td_api::viewMessages> viewMessagesReq = td::td_api::make_object<td::td_api::viewMessages>();
|
||||
viewMessagesReq->chat_id_ = chatId.value();
|
||||
viewMessagesReq->force_read_ = true; // no idea what "closed chats" are at this point
|
||||
viewMessagesReq->message_ids_.resize(receipts.size());
|
||||
for (size_t i = 0; i < receipts.size(); i++)
|
||||
viewMessagesReq->message_ids_[i] = receipts[i].messageId.value();
|
||||
account.transceiver.sendQuery(std::move(viewMessagesReq), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void showMessageTextIm(TdAccountData &account, const char *purpleUserName, const char *text,
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _RECEIVING_H
|
||||
|
||||
#include "account-data.h"
|
||||
#include "transceiver.h"
|
||||
#include <purple.h>
|
||||
|
||||
std::string makeNoticeWithSender(const td::td_api::chat &chat, const TgMessageInfo &message,
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _SECRET_CHAT_H
|
||||
|
||||
#include "account-data.h"
|
||||
#include "transceiver.h"
|
||||
#include "format.h"
|
||||
|
||||
void updateSecretChat(td::td_api::object_ptr<td::td_api::secretChat> secretChat,
|
||||
|
@ -20,7 +20,7 @@ enum {
|
||||
|
||||
PurpleTdClient::PurpleTdClient(PurpleAccount *acct, ITransceiverBackend *testBackend)
|
||||
: m_transceiver(this, acct, &PurpleTdClient::processUpdate, testBackend),
|
||||
m_data(acct)
|
||||
m_data(acct, m_transceiver)
|
||||
{
|
||||
StickerConversionThread::setCallback(&PurpleTdClient::onAnimatedStickerConverted);
|
||||
m_account = acct;
|
||||
@ -919,28 +919,6 @@ void PurpleTdClient::sendReadReceipts(PurpleConversation *conversation)
|
||||
sendConversationReadReceipts(m_data, conversation);
|
||||
return;
|
||||
}
|
||||
|
||||
// temporary
|
||||
std::vector<ReadReceipt> receipts;
|
||||
m_data.extractPendingReadReceipts(receipts);
|
||||
|
||||
std::sort(receipts.begin(), receipts.end(),
|
||||
[](const ReadReceipt &r1, const ReadReceipt &r2) {
|
||||
return (r1.chatId.value() < r2.chatId.value());
|
||||
});
|
||||
|
||||
unsigned i = 0;
|
||||
while (i < receipts.size()) {
|
||||
ChatId chatId = receipts[i].chatId;
|
||||
td::td_api::object_ptr<td::td_api::viewMessages> viewMessagesReq = td::td_api::make_object<td::td_api::viewMessages>();
|
||||
viewMessagesReq->chat_id_ = chatId.value();
|
||||
viewMessagesReq->force_read_ = true; // no idea what "closed chats" are at this point
|
||||
while ((i < receipts.size()) && (receipts[i].chatId == chatId)) {
|
||||
viewMessagesReq->message_ids_.push_back(receipts[i].messageId.value());
|
||||
i++;
|
||||
}
|
||||
m_transceiver.sendQuery(std::move(viewMessagesReq), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PurpleTdClient::onIncomingMessage(td::td_api::object_ptr<td::td_api::message> message)
|
||||
@ -956,10 +934,8 @@ void PurpleTdClient::onIncomingMessage(td::td_api::object_ptr<td::td_api::messag
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReadReceiptsEnabled(m_account)) {
|
||||
if (isReadReceiptsEnabled(m_account))
|
||||
m_data.addPendingReadReceipt(chatId, getId(*message));
|
||||
sendReadReceipts(NULL);
|
||||
}
|
||||
|
||||
IncomingMessage fullMessage;
|
||||
makeFullMessage(*chat, std::move(message), fullMessage, m_data);
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define _TD_CLIENT_H
|
||||
|
||||
#include "account-data.h"
|
||||
#include "transceiver.h"
|
||||
#include "client-utils.h"
|
||||
#include <td/telegram/Log.h>
|
||||
#include <purple.h>
|
||||
|
@ -276,12 +276,22 @@ void tgprpl_set_single_thread()
|
||||
AccountThread::setSingleThread();
|
||||
}
|
||||
|
||||
struct PurpleConversationInfo {
|
||||
std::string accountName;
|
||||
std::string convName;
|
||||
PurpleConversationType type;
|
||||
};
|
||||
|
||||
static gboolean sendConversationReadReceipts(void *arg)
|
||||
{
|
||||
PurpleConversation *conv = static_cast<PurpleConversation *>(arg);
|
||||
PurpleTdClient *tdClient = getTdClient(purple_conversation_get_account(conv));
|
||||
std::unique_ptr<PurpleConversationInfo> info(static_cast<PurpleConversationInfo *>(arg));
|
||||
PurpleAccount *account = purple_accounts_find(info->accountName.c_str(), config::pluginId);
|
||||
PurpleConversation *conv = NULL;
|
||||
if (account != NULL)
|
||||
conv = purple_find_conversation_with_account(info->type, info->convName.c_str(), account);
|
||||
|
||||
tdClient->sendReadReceipts(conv);
|
||||
if (conv != NULL)
|
||||
getTdClient(account)->sendReadReceipts(conv);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@ -293,7 +303,11 @@ conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type)
|
||||
if (!strcmp(purple_account_get_protocol_id(account), config::pluginId) &&
|
||||
(type == PURPLE_CONV_UPDATE_UNSEEN))
|
||||
{
|
||||
g_timeout_add(500, sendConversationReadReceipts, conv);
|
||||
PurpleConversationInfo *arg = new PurpleConversationInfo;
|
||||
arg->accountName = purple_account_get_username(account);
|
||||
arg->convName = purple_conversation_get_name(conv);
|
||||
arg->type = purple_conversation_get_type(conv);
|
||||
g_timeout_add(500, sendConversationReadReceipts, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user