summaryrefslogtreecommitdiff
path: root/protocols/Telegram/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-11-22 13:32:54 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-11-22 13:32:54 +0300
commit0efb03cfe2e0d4ee89ee3804e4c35501b6cc12dc (patch)
tree4c8dc3ff81950abaf724d909cfcf64249a07259e /protocols/Telegram/src
parent114e7ce32efdc1f4a33f8160efb5d5c797e45d3f (diff)
fixes #3947 (Telegram: formatting support)
Diffstat (limited to 'protocols/Telegram/src')
-rw-r--r--protocols/Telegram/src/proto.cpp8
-rw-r--r--protocols/Telegram/src/server.cpp3
-rw-r--r--protocols/Telegram/src/utils.cpp95
-rw-r--r--protocols/Telegram/src/utils.h2
4 files changed, 90 insertions, 18 deletions
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<TD::formattedText>();
- text->text_ = (char*)dbei.pBlob;
-
+ auto text = formatBbcodes((char*)dbei.pBlob);
auto content = TD::make_object<TD::inputMessageText>(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<TD::formattedText>();
- caption->text_ = T2Utf(szDescription).get();
+
+ auto caption = formatBbcodes(T2Utf(szDescription));
if (pTransfer->m_type == TG_FILE_REQUEST::FILE) {
auto pContent = TD::make_object<TD::inputMessageDocument>();
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<TD::inputMessageText>();
- pContent->text_ = TD::make_object<TD::formattedText>();
- 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 <http://www.gnu.org/licenses/>.
#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<TD::formattedText> formatBbcodes(const char *pszText)
+{
+ auto res = TD::make_object<TD::formattedText>();
+ 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<TD::TextEntityType> pNew;
+ switch (it.begin[1]) {
+ case 'b': pNew = TD::make_object<TD::textEntityTypeBold>(); break;
+ case 'i': pNew = TD::make_object<TD::textEntityTypeItalic>(); break;
+ case 's': pNew = TD::make_object<TD::textEntityTypeStrikethrough>(); break;
+ case 'u': pNew = TD::make_object<TD::textEntityTypeUnderline>(); break;
+ }
+
+ res->entities_.push_back(TD::make_object<TD::textEntity>(TD::int32(i1), TD::int32(i2 - i1), std::move(pNew)));
+ }
+ }
+ res->text_ = str;
+ }
+
+ return res;
+}
+
+static CMStringA getFormattedText(TD::object_ptr<TD::formattedText> &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<TD::formattedText> &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<TD::inputFileLocal> makeFile(const CMStringW &wszFile);
+
+TD::object_ptr<TD::formattedText> formatBbcodes(const char *pszText);