2
0
mirror of https://github.com/ars3niy/tdlib-purple synced 2025-09-01 06:25:10 +00:00

Refactored stickers

This commit is contained in:
Arseniy Lartsev
2020-05-12 13:01:18 +02:00
parent b3857896a6
commit c294fa1781
3 changed files with 123 additions and 110 deletions

View File

@@ -34,11 +34,6 @@ public:
: PendingRequest(requestId), groupId(groupId) {} : PendingRequest(requestId), groupId(groupId) {}
}; };
enum class FileFallback: uint8_t {
None,
ReplaceTgs,
};
// Matching completed downloads to chats they belong to // Matching completed downloads to chats they belong to
class DownloadRequest: public PendingRequest { class DownloadRequest: public PendingRequest {
public: public:
@@ -46,15 +41,13 @@ public:
std::string sender; std::string sender;
int32_t timestamp; int32_t timestamp;
bool outgoing; bool outgoing;
std::string label; td::td_api::object_ptr<td::td_api::file> thumbnail;
FileFallback fallbackType;
td::td_api::object_ptr<td::td_api::file> fallback;
// Could not pass object_ptr through variadic funciton :(
DownloadRequest(uint64_t requestId, int64_t chatId, const std::string &sender, int32_t timestamp, DownloadRequest(uint64_t requestId, int64_t chatId, const std::string &sender, int32_t timestamp,
bool outgoing, const std::string &label, FileFallback fallbackType, bool outgoing, td::td_api::file *thumbnail)
td::td_api::file *fallback)
: PendingRequest(requestId), chatId(chatId), sender(sender), timestamp(timestamp), : PendingRequest(requestId), chatId(chatId), sender(sender), timestamp(timestamp),
outgoing(outgoing), label(label), fallbackType(fallbackType), fallback(fallback) {} outgoing(outgoing), thumbnail(thumbnail) {}
}; };
class TdAccountData { class TdAccountData {

View File

@@ -559,6 +559,23 @@ void PurpleTdClient::showPhotoMessage(const td::td_api::chat &chat, const td::td
showImage(chat, message, *file); showImage(chat, message, *file);
} }
void PurpleTdClient::requestDownload(int32_t fileId, int64_t chatId, const std::string &sender,
int32_t timestamp, bool outgoing,
td::td_api::object_ptr<td::td_api::file> thumbnail,
TdTransceiver::ResponseCb responseCb)
{
td::td_api::object_ptr<td::td_api::downloadFile> downloadReq =
td::td_api::make_object<td::td_api::downloadFile>();
downloadReq->file_id_ = fileId;
downloadReq->priority_ = FILE_DOWNLOAD_PRIORITY;
downloadReq->offset_ = 0;
downloadReq->limit_ = 0;
downloadReq->synchronous_ = true;
uint64_t requestId = m_transceiver.sendQuery(std::move(downloadReq), responseCb);
m_data.addPendingRequest<DownloadRequest>(requestId, chatId, sender, timestamp, outgoing, thumbnail.release());
}
void PurpleTdClient::showImage(const td::td_api::chat &chat, const td::td_api::message &message, void PurpleTdClient::showImage(const td::td_api::chat &chat, const td::td_api::message &message,
const td::td_api::file &file) const td::td_api::file &file)
{ {
@@ -568,41 +585,36 @@ void PurpleTdClient::showImage(const td::td_api::chat &chat, const td::td_api::m
showDownloadedImage(chat.id_, sender, message.date_, message.is_outgoing_, file.local_->path_); showDownloadedImage(chat.id_, sender, message.date_, message.is_outgoing_, file.local_->path_);
else { else {
purple_debug_misc(config::pluginId, "Downloading image (file id %d)\n", (int)file.id_); purple_debug_misc(config::pluginId, "Downloading image (file id %d)\n", (int)file.id_);
td::td_api::object_ptr<td::td_api::downloadFile> downloadReq = requestDownload(file.id_, chat.id_, sender, message.date_, message.is_outgoing_,
td::td_api::make_object<td::td_api::downloadFile>(); nullptr, &PurpleTdClient::imageDownloadResponse);
downloadReq->file_id_ = file.id_;
downloadReq->priority_ = FILE_DOWNLOAD_PRIORITY;
downloadReq->offset_ = 0;
downloadReq->limit_ = 0;
downloadReq->synchronous_ = true;
uint64_t requestId = m_transceiver.sendQuery(std::move(downloadReq),
&PurpleTdClient::imageDownloadResponse);
m_data.addPendingRequest<DownloadRequest>(requestId, message.chat_id_, sender, message.date_,
message.is_outgoing_, "", FileFallback::None, nullptr);
} }
} }
static std::string getDownloadPath(const td::td_api::Object *object)
{
if (!object)
purple_debug_misc(config::pluginId, "No response after downloading file\n");
else if (object->get_id() == td::td_api::file::ID) {
const td::td_api::file &file = static_cast<const td::td_api::file &>(*object);
if (!file.local_)
purple_debug_misc(config::pluginId, "No local file info after downloading\n");
else if (!file.local_->is_downloading_completed_)
purple_debug_misc(config::pluginId, "File not completely downloaded\n");
else
return file.local_->path_;
} else
purple_debug_misc(config::pluginId, "Unexpected response to downloading file: id %d\n",
(int)object->get_id());
return "";
}
void PurpleTdClient::imageDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object) void PurpleTdClient::imageDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object)
{ {
std::string path; std::string path = getDownloadPath(object.get());
std::unique_ptr<DownloadRequest> request = m_data.getPendingRequest<DownloadRequest>(requestId); std::unique_ptr<DownloadRequest> request = m_data.getPendingRequest<DownloadRequest>(requestId);
if (!request)
return;
if (object->get_id() == td::td_api::file::ID) { if (request && !path.empty()) {
const td::td_api::file &file = static_cast<const td::td_api::file &>(*object);
if (!file.local_)
purple_debug_misc(config::pluginId, "No local file info after downloading photo\n");
else if (!file.local_->is_downloading_completed_)
purple_debug_misc(config::pluginId, "Image not completely downloaded\n");
else
path = file.local_->path_;
} else
purple_debug_misc(config::pluginId, "Unexpected response to downloading image: id %d\n",
(int)object->get_id());
if (!path.empty()) {
purple_debug_misc(config::pluginId, "Image downloaded, path: %s\n", path.c_str()); purple_debug_misc(config::pluginId, "Image downloaded, path: %s\n", path.c_str());
showDownloadedImage(request->chatId, request->sender, request->timestamp, request->outgoing, path); showDownloadedImage(request->chatId, request->sender, request->timestamp, request->outgoing, path);
} }
@@ -656,63 +668,19 @@ void PurpleTdClient::showSticker(const td::td_api::chat &chat, const td::td_api:
if (!stickerContent.sticker_) return; if (!stickerContent.sticker_) return;
td::td_api::sticker &sticker = *stickerContent.sticker_; td::td_api::sticker &sticker = *stickerContent.sticker_;
if (sticker.sticker_) if (sticker.sticker_) {
showInlineFile(chat, getSenderPurpleName(chat, message, m_data), message.date_, std::string sender = getSenderPurpleName(chat, message, m_data);
message.is_outgoing_, *sticker.sticker_, "Sticker", FileFallback::ReplaceTgs, auto thumbnail = sticker.thumbnail_ ? std::move(sticker.thumbnail_->photo_) : nullptr;
sticker.thumbnail_ ? std::move(sticker.thumbnail_->photo_) : nullptr);
}
void PurpleTdClient::showInlineFile(const td::td_api::chat &chat, const std::string &sender, if (sticker.sticker_->local_ && sticker.sticker_->local_->is_downloading_completed_)
int32_t timestamp, bool outgoing, showDownloadedSticker(chat.id_, sender, message.date_, message.is_outgoing_,
const td::td_api::file &file, const char *label, sticker.sticker_->local_->path_, std::move(thumbnail));
FileFallback fallbackType, else {
td::td_api::object_ptr<td::td_api::file> fallback) purple_debug_misc(config::pluginId, "Downloading sticker (file id %d)\n", (int)sticker.sticker_->id_);
{ requestDownload(sticker.sticker_->id_, chat.id_, getSenderPurpleName(chat, message, m_data),
if (file.local_ && file.local_->is_downloading_completed_) message.date_, message.is_outgoing_, std::move(thumbnail),
showDownloadedInlineFile(chat.id_, sender, timestamp, outgoing, &PurpleTdClient::stickerDownloadResponse);
file.local_->path_, label, fallbackType, std::move(fallback)); }
else {
purple_debug_misc(config::pluginId, "Downloading file (id %d)\n", (int)file.id_);
td::td_api::object_ptr<td::td_api::downloadFile> downloadReq =
td::td_api::make_object<td::td_api::downloadFile>();
downloadReq->file_id_ = file.id_;
downloadReq->priority_ = FILE_DOWNLOAD_PRIORITY;
downloadReq->offset_ = 0;
downloadReq->limit_ = 0;
downloadReq->synchronous_ = true;
uint64_t requestId = m_transceiver.sendQuery(std::move(downloadReq),
&PurpleTdClient::fileDownloadResponse);
m_data.addPendingRequest<DownloadRequest>(requestId, chat.id_, sender, timestamp,
outgoing, label, fallbackType,
fallback.release());
}
}
void PurpleTdClient::fileDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object)
{
std::string path;
std::unique_ptr<DownloadRequest> request = m_data.getPendingRequest<DownloadRequest>(requestId);
if (!request)
return;
if (object->get_id() == td::td_api::file::ID) {
const td::td_api::file &file = static_cast<const td::td_api::file &>(*object);
if (!file.local_)
purple_debug_misc(config::pluginId, "No local file info after downloading\n");
else if (!file.local_->is_downloading_completed_)
purple_debug_misc(config::pluginId, "File not completely downloaded\n");
else
path = file.local_->path_;
} else
purple_debug_misc(config::pluginId, "Unexpected response to downloading file: id %d\n",
(int)object->get_id());
if (!path.empty()) {
purple_debug_misc(config::pluginId, "File downloaded, path: %s\n", path.c_str());
showDownloadedInlineFile(request->chatId, request->sender, request->timestamp,
request->outgoing, path, request->label.c_str(),
request->fallbackType, std::move(request->fallback));
} }
} }
@@ -725,19 +693,66 @@ static bool isTgs(const std::string &path)
return false; return false;
} }
void PurpleTdClient::stickerDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object)
{
std::string path = getDownloadPath(object.get());
std::unique_ptr<DownloadRequest> request = m_data.getPendingRequest<DownloadRequest>(requestId);
if (request && !path.empty())
showDownloadedSticker(request->chatId, request->sender, request->timestamp, request->outgoing,
path, std::move(request->thumbnail));
}
void PurpleTdClient::showDownloadedSticker(int64_t chatId, const std::string &sender, int32_t timestamp,
bool outgoing, const std::string &filePath,
td::td_api::object_ptr<td::td_api::file> thumbnail)
{
if (isTgs(filePath) && thumbnail) {
if (thumbnail->local_ && thumbnail->local_->is_downloading_completed_)
showDownloadedInlineFile(chatId, sender, timestamp, outgoing,
thumbnail->local_->path_, "Sticker");
else
requestDownload(thumbnail->id_, chatId, sender,
timestamp, outgoing, nullptr,
&PurpleTdClient::stickerDownloadResponse);
} else
showDownloadedInlineFile(chatId, sender, timestamp, outgoing, filePath, "Sticker");
}
void PurpleTdClient::showInlineFile(const td::td_api::chat &chat, const td::td_api::message &message,
const td::td_api::file &file)
{
std::string sender = getSenderPurpleName(chat, message, m_data);
if (file.local_ && file.local_->is_downloading_completed_)
showDownloadedInlineFile(chat.id_, sender, message.date_, message.is_outgoing_,
file.local_->path_, "Sent file");
else {
purple_debug_misc(config::pluginId, "Downloading file (id %d)\n", (int)file.id_);
requestDownload(file.id_, chat.id_, sender, message.date_, message.is_outgoing_, nullptr,
&PurpleTdClient::fileDownloadResponse);
}
}
void PurpleTdClient::fileDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object)
{
std::string path = getDownloadPath(object.get());
std::unique_ptr<DownloadRequest> request = m_data.getPendingRequest<DownloadRequest>(requestId);
if (request && !path.empty()) {
purple_debug_misc(config::pluginId, "File downloaded, path: %s\n", path.c_str());
showDownloadedInlineFile(request->chatId, request->sender, request->timestamp,
request->outgoing, path, "Sent file");
}
}
void PurpleTdClient::showDownloadedInlineFile(int64_t chatId, const std::string &sender, int32_t timestamp, void PurpleTdClient::showDownloadedInlineFile(int64_t chatId, const std::string &sender, int32_t timestamp,
bool outgoing, const std::string &filePath, const char *label, bool outgoing, const std::string &filePath, const char *label)
FileFallback fallbackType,
td::td_api::object_ptr<td::td_api::file> fallback)
{ {
const td::td_api::chat *chat = m_data.getChat(chatId); const td::td_api::chat *chat = m_data.getChat(chatId);
if (chat) { if (chat) {
if ((fallbackType == FileFallback::ReplaceTgs && isTgs(filePath)) && fallback) {
showInlineFile(*chat, sender, timestamp, outgoing, *fallback, label,
FileFallback::None, nullptr);
return;
}
if (filePath.find('"') != std::string::npos) if (filePath.find('"') != std::string::npos)
showMessageText(m_account, *chat, sender, NULL, showMessageText(m_account, *chat, sender, NULL,
"Cannot show file: path contains quotes", timestamp, outgoing, m_data); "Cannot show file: path contains quotes", timestamp, outgoing, m_data);

View File

@@ -69,18 +69,23 @@ private:
void addContactCreatePrivateChatResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object); void addContactCreatePrivateChatResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object);
void notifyFailedContact(const std::string &phoneNumber, const std::string &errorMessage); void notifyFailedContact(const std::string &phoneNumber, const std::string &errorMessage);
void requestDownload(int32_t fileId, int64_t chatId, const std::string &sender,
int32_t timestamp, bool outgoing,
td::td_api::object_ptr<td::td_api::file> thumbnail,
TdTransceiver::ResponseCb responseCb);
void showImage(const td::td_api::chat &chat, const td::td_api::message &message, const td::td_api::file &file); void showImage(const td::td_api::chat &chat, const td::td_api::message &message, const td::td_api::file &file);
void imageDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object); void imageDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object);
void showDownloadedImage(int64_t chatId, const std::string &sender, int32_t timestamp, bool outgoing, void showDownloadedImage(int64_t chatId, const std::string &sender, int32_t timestamp, bool outgoing,
const std::string &filePath); const std::string &filePath);
void showInlineFile(const td::td_api::chat &chat, const std::string &sender, int32_t timestamp, bool outgoing, void showInlineFile(const td::td_api::chat &chat, const td::td_api::message &message,
const td::td_api::file &file, const char *label, FileFallback fallbackType, const td::td_api::file &file);
td::td_api::object_ptr<td::td_api::file> fallback);
void fileDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object); void fileDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object);
void showDownloadedInlineFile(int64_t chatId, const std::string &sender, int32_t timestamp, void showDownloadedInlineFile(int64_t chatId, const std::string &sender, int32_t timestamp,
bool outgoing, const std::string &filePath, const char *label, bool outgoing, const std::string &filePath, const char *label);
FileFallback fallbackType, void stickerDownloadResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object);
td::td_api::object_ptr<td::td_api::file> fallback); void showDownloadedSticker(int64_t chatId, const std::string &sender, int32_t timestamp,
bool outgoing, const std::string &filePath,
td::td_api::object_ptr<td::td_api::file> thumbnail);
PurpleAccount *m_account; PurpleAccount *m_account;
TdTransceiver m_transceiver; TdTransceiver m_transceiver;