From 0efb03cfe2e0d4ee89ee3804e4c35501b6cc12dc Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 22 Nov 2023 13:32:54 +0300 Subject: fixes #3947 (Telegram: formatting support) --- protocols/Telegram/src/proto.cpp | 8 ++-- protocols/Telegram/src/server.cpp | 3 +- protocols/Telegram/src/utils.cpp | 95 ++++++++++++++++++++++++++++++++++----- protocols/Telegram/src/utils.h | 2 + 4 files changed, 90 insertions(+), 18 deletions(-) (limited to 'protocols') diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp index 6997ff8374..f3ea4f43e5 100644 --- a/protocols/Telegram/src/proto.cpp +++ b/protocols/Telegram/src/proto.cpp @@ -234,9 +234,7 @@ void CTelegramProto::OnEventEdited(MCONTACT hContact, MEVENT, const DBEVENTINFO return; if (dbei.szId && dbei.cbBlob && dbei.pBlob && dbei.eventType == EVENTTYPE_MESSAGE) { - auto text = TD::make_object(); - text->text_ = (char*)dbei.pBlob; - + auto text = formatBbcodes((char*)dbei.pBlob); auto content = TD::make_object(std::move(text), false, false); SendQuery(new TD::editMessageText(pUser->chatId, _atoi64(dbei.szId), 0, std::move(content))); } @@ -424,8 +422,8 @@ HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, // create a message with embedded file auto *pMessage = new TD::sendMessage(); pMessage->chat_id_ = pUser->chatId; - auto caption = TD::make_object(); - caption->text_ = T2Utf(szDescription).get(); + + auto caption = formatBbcodes(T2Utf(szDescription)); if (pTransfer->m_type == TG_FILE_REQUEST::FILE) { auto pContent = TD::make_object(); diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index 9baa1fe26c..f0315de203 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -309,8 +309,7 @@ void CTelegramProto::OnSendMessage(td::ClientManager::Response &response) int CTelegramProto::SendTextMessage(int64_t chatId, const char *pszMessage) { auto pContent = TD::make_object(); - pContent->text_ = TD::make_object(); - pContent->text_->text_ = std::move(pszMessage); + pContent->text_ = formatBbcodes(pszMessage); auto *pMessage = new TD::sendMessage(); pMessage->chat_id_ = chatId; diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp index 95cde5afb3..c517529219 100644 --- a/protocols/Telegram/src/utils.cpp +++ b/protocols/Telegram/src/utils.cpp @@ -17,6 +17,86 @@ along with this program. If not, see . #include "stdafx.h" +struct +{ + const char *begin, *end; + unsigned len1, len2; +} +static bbCodes[] = +{ + { "[b]", "[/b]", 3, 4 }, + { "[i]", "[/i]", 3, 4 }, + { "[s]", "[/s]", 3, 4 }, + { "[u]", "[/u]", 3, 4 }, +}; + +TD::object_ptr formatBbcodes(const char *pszText) +{ + auto res = TD::make_object(); + if (mir_strlen(pszText)) { + std::string str = pszText; + for (auto &it : bbCodes) { + while (true) { + size_t i1 = str.find(it.begin); + if (i1 == str.npos) + break; + + size_t i2 = str.find(it.end, i1); + if (i2 == str.npos) + break; + + for (auto &jt : res->entities_) { + if (jt->offset_ > i1) + jt->offset_ -= it.len1; + if (jt->offset_ > i2) + jt->offset_ -= it.len2; + } + + str.erase(i2, it.len2); i2 -= it.len1; + str.erase(i1, it.len1); + + TD::object_ptr pNew; + switch (it.begin[1]) { + case 'b': pNew = TD::make_object(); break; + case 'i': pNew = TD::make_object(); break; + case 's': pNew = TD::make_object(); break; + case 'u': pNew = TD::make_object(); break; + } + + res->entities_.push_back(TD::make_object(TD::int32(i1), TD::int32(i2 - i1), std::move(pNew))); + } + } + res->text_ = str; + } + + return res; +} + +static CMStringA getFormattedText(TD::object_ptr &pText) +{ + if (pText->get_id() == TD::formattedText::ID) { + CMStringA ret(pText->text_.c_str()); + for (auto &it : pText->entities_) { + int iCode; + switch (it->get_id()) { + case TD::textEntityTypeBold::ID: iCode = 0; break; + case TD::textEntityTypeItalic::ID: iCode = 1; break; + case TD::textEntityTypeStrikethrough::ID: iCode = 2; break; + case TD::textEntityTypeUnderline::ID: iCode = 3; break; + default: + continue; + } + + ret.Insert(it->offset_ + it->length_, bbCodes[iCode].end); + ret.Insert(it->offset_, bbCodes[iCode].begin); + } + } + + return ""; +} + +///////////////////////////////////////////////////////////////////////////////////////// + const char *getName(const TD::usernames *pName) { return (pName == nullptr) ? TranslateU("none") : pName->editable_username_.c_str(); @@ -349,13 +429,6 @@ static bool checkStickerType(uint32_t ID) } } -static const char *getFormattedText(TD::object_ptr &pText) -{ - if (pText->get_id() == TD::formattedText::ID) - return pText->text_.c_str(); - return nullptr; -} - CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg) { const TD::MessageContent *pBody = pMsg->content_.get(); @@ -480,14 +553,14 @@ CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg CMStringA ret(FORMAT, "%s: %.2lf %s", TranslateU("You received an invoice"), double(pInvoice->total_amount_)/100.0, pInvoice->currency_.c_str()); if (!pInvoice->title_.empty()) ret.AppendFormat("\r\n%s: %s", TranslateU("Title"), pInvoice->title_.c_str()); - if (auto *pszText = getFormattedText(pInvoice->description_)) - ret.AppendFormat("\r\n%s", ((TD::formattedText *)pInvoice->description_.get())->text_.c_str()); + if (auto pszText = getFormattedText(pInvoice->description_)) + ret.AppendFormat("\r\n%s", pszText.c_str()); return ret; } case TD::messageText::ID: - if (auto *pszText = getFormattedText(((TD::messageText *)pBody)->text_)) - return CMStringA(pszText); + if (auto pszText = getFormattedText(((TD::messageText *)pBody)->text_)) + return pszText; break; } diff --git a/protocols/Telegram/src/utils.h b/protocols/Telegram/src/utils.h index ad42a3e425..914ac7d1d4 100644 --- a/protocols/Telegram/src/utils.h +++ b/protocols/Telegram/src/utils.h @@ -3,3 +3,5 @@ const char *getName(const TD::usernames *pName); TD::object_ptr makeFile(const CMStringW &wszFile); + +TD::object_ptr formatBbcodes(const char *pszText); -- cgit v1.2.3