diff options
Diffstat (limited to 'protocols/Telegram/src/utils.cpp')
-rw-r--r-- | protocols/Telegram/src/utils.cpp | 131 |
1 files changed, 108 insertions, 23 deletions
diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp index 4d06f7b807..7589abd500 100644 --- a/protocols/Telegram/src/utils.cpp +++ b/protocols/Telegram/src/utils.cpp @@ -1,5 +1,5 @@ /*
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -22,7 +22,7 @@ enum class BBCODE BOLD, ITALIC, STRIKE, UNDERLINE, URL, CODE, QUOTE
};
-struct
+struct Bbcode
{
BBCODE type;
const wchar_t *begin, *end;
@@ -75,6 +75,13 @@ TD::object_ptr<TD::formattedText> formatBbcodes(const char *pszText) case BBCODE::UNDERLINE: pNew = TD::make_object<TD::textEntityTypeUnderline>(); break;
}
+ for (auto &jt : res->entities_) {
+ if (i1 >= jt->offset_ && i1 < jt->offset_ + jt->length_)
+ jt->length_ -= it.len1;
+ if (i2 >= jt->offset_ && i2 < jt->offset_ + jt->length_)
+ jt->length_ -= it.len2;
+ }
+
res->entities_.push_back(TD::make_object<TD::textEntity>(TD::int32(i1), TD::int32(i2 - i1), std::move(pNew)));
}
}
@@ -87,7 +94,12 @@ TD::object_ptr<TD::formattedText> formatBbcodes(const char *pszText) CMStringA CTelegramProto::GetFormattedText(TD::object_ptr<TD::formattedText> &pText)
{
CMStringW ret(Utf2T(pText->text_.c_str()));
- unsigned offset = 0;
+
+ struct HistItem {
+ HistItem(int _1, int _2, const Bbcode &_3) : start(_1), length(_2), l1(_3.len1), l2(_3.len2) {}
+ int start, length, l1, l2;
+ };
+ std::vector<HistItem> history;
for (auto &it : pText->entities_) {
int iCode;
@@ -103,10 +115,30 @@ CMStringA CTelegramProto::GetFormattedText(TD::object_ptr<TD::formattedText> &pT continue;
}
+ int off1 = 0, off2 = 0;
+ for (auto &h : history) {
+ if (it->offset_ >= h.start)
+ off1 += h.l1;
+ if (it->offset_ + it->length_ > h.start)
+ off2 += h.l1;
+ if (it->offset_ >= h.start + h.length)
+ off1 += h.l2;
+ if (it->offset_ + it->length_ > h.start + h.length)
+ off2 += h.l2;
+ }
+
auto &bb = bbCodes[iCode];
- ret.Insert(offset + it->offset_ + it->length_, bb.end);
- ret.Insert(offset + it->offset_, bb.begin);
- offset += bb.len1 + bb.len2;
+ HistItem histItem(it->offset_, it->length_, bb);
+ ret.Insert(off2 + it->offset_ + it->length_, bb.end);
+ ret.Insert(off1 + it->offset_, bb.begin);
+ if (iCode == 4) {
+ auto *pUrl = (TD::textEntityTypeTextUrl *)it->type_.get();
+ Utf2T wszUrl(pUrl->url_.c_str());
+ ret.Insert(off1 + it->offset_ + 4, wszUrl);
+ ret.Insert(off1 + it->offset_ + 4, L"=");
+ histItem.l1 += 1 + (int)mir_wstrlen(wszUrl);
+ }
+ history.push_back(histItem);
}
return T2Utf(ret).get();
}
@@ -120,7 +152,11 @@ CMStringA msg2id(TD::int53 chatId, TD::int53 msgId) CMStringA msg2id(const TD::message *pMsg)
{
- return CMStringA(FORMAT, "%lld_%lld", pMsg->chat_id_, pMsg->id_);
+ auto iChatId = pMsg->chat_id_;
+ if (!iChatId && pMsg->sender_id_->get_id() == TD::messageSenderChat::ID)
+ iChatId = ((TD::messageSenderChat *)pMsg->sender_id_.get())->chat_id_;
+
+ return CMStringA(FORMAT, "%lld_%lld", iChatId, pMsg->id_);
}
TD::int53 dbei2id(const DBEVENTINFO &dbei)
@@ -147,19 +183,29 @@ TD::object_ptr<TD::inputFileLocal> makeFile(const wchar_t *pwszFilename) TG_FILE_REQUEST::Type AutoDetectType(const wchar_t *pwszFilename)
{
- if (ProtoGetAvatarFileFormat(pwszFilename) != PA_FORMAT_UNKNOWN)
- return TG_FILE_REQUEST::PICTURE;
+ if (int iFormat = ProtoGetAvatarFileFormat(pwszFilename)) {
+ if (iFormat != PA_FORMAT_GIF)
+ return TG_FILE_REQUEST::PICTURE;
+
+ if (auto *pBitmap = FreeImage_OpenMultiBitmapU(FIF_GIF, pwszFilename, FALSE, TRUE)) {
+ int iPages = FreeImage_GetPageCount(pBitmap);
+ FreeImage_CloseMultiBitmap(pBitmap);
+ if (iPages <= 1)
+ return TG_FILE_REQUEST::PICTURE;
+ }
+ }
CMStringW path(pwszFilename);
int idx = path.ReverseFind('.');
if (idx == -1 || path.Find('\\', idx) != -1)
return TG_FILE_REQUEST::FILE;
- auto wszExt = path.Right(path.GetLength() - idx);
+ auto wszExt = path.Right(path.GetLength() - idx - 1);
wszExt.MakeLower();
- if (wszExt == L"mp4" || wszExt == L"webm")
+ if (wszExt == L"mp4" || wszExt == L"webm" || wszExt == L"gif")
return TG_FILE_REQUEST::VIDEO;
- else if (wszExt == L"mp3" || wszExt == "ogg" || wszExt == "oga" || wszExt == "wav")
+
+ if (wszExt == L"mp3" || wszExt == "ogg" || wszExt == "oga" || wszExt == "wav")
return TG_FILE_REQUEST::VOICE;
return TG_FILE_REQUEST::FILE;
@@ -216,11 +262,10 @@ void CTelegramProto::MarkRead(MCONTACT hContact, const CMStringA &szMaxId, bool if (dbei.szId > szMaxId)
break;
- bool isSent = (dbei.flags & DBEF_SENT) != 0;
- if (isSent != bSent)
+ if (dbei.bSent != bSent)
continue;
- if (!dbei.markedRead())
+ if (!dbei.bRead)
db_event_markRead(hContact, hEvent, true);
}
}
@@ -232,8 +277,12 @@ int CTelegramProto::GetDefaultMute(const TG_USER *pUser) return m_iDefaultMutePrivate;
}
-MCONTACT CTelegramProto::GetRealContact(const TG_USER *pUser)
+MCONTACT CTelegramProto::GetRealContact(const TG_USER *pUser, int64_t threadId)
{
+ if (threadId)
+ if (auto *pu = FindChat(pUser->chatId, threadId))
+ return pu->hContact;
+
return (pUser->hContact != 0) ? pUser->hContact : m_iSavedMessages;
}
@@ -252,6 +301,21 @@ TG_USER* CTelegramProto::GetSender(const TD::MessageSender *pSender) /////////////////////////////////////////////////////////////////////////////////////////
+void CTelegramProto::CheckCompatibility()
+{
+ int iLevel = db_get_b(0, "Compatibility", m_szModuleName);
+
+ if (iLevel < 1) {
+ for (auto &cc : AccContacts())
+ delSetting(cc, "Notes");
+ delSetting("Notes");
+ }
+
+ db_set_b(0, "Compatibility", m_szModuleName, 1);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
bool CTelegramProto::CheckSearchUser(TG_USER *pUser)
{
auto pSearchId = std::find(m_searchIds.begin(), m_searchIds.end(), pUser->chatId);
@@ -317,6 +381,12 @@ void CTelegramProto::UpdateString(MCONTACT hContact, const char *pszSetting, con setUString(hContact, pszSetting, str.c_str());
}
+TG_SUPER_GROUP* CTelegramProto::FindSuperGroup(int64_t id)
+{
+ TG_SUPER_GROUP tmp(id, 0);
+ return m_arSuperGroups.find(&tmp);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// Users
@@ -324,6 +394,15 @@ TG_USER* CTelegramProto::FindChat(int64_t id) {
auto *tmp = (TG_USER *)_alloca(sizeof(TG_USER));
tmp->chatId = id;
+ tmp->forumId = -1;
+ return m_arChats.find(tmp);
+}
+
+TG_USER* CTelegramProto::FindChat(int64_t id, int64_t forumId)
+{
+ auto *tmp = (TG_USER *)_alloca(sizeof(TG_USER));
+ tmp->chatId = id;
+ tmp->forumId = forumId;
return m_arChats.find(tmp);
}
@@ -366,6 +445,8 @@ TG_USER* CTelegramProto::AddUser(int64_t id, bool bIsChat) }
else {
pUser->hContact = hContact;
+ if (pUser->wszNick[0] == '@')
+ pUser->wszNick.Delete(0, 1);
setWString(hContact, "Nick", pUser->wszNick);
if (!pUser->isGroupChat) {
setWString(hContact, "FirstName", pUser->wszFirstName);
@@ -452,7 +533,7 @@ bool CTelegramProto::GetMessageFile(const EmbeddedFile &F, TG_FILE_REQUEST::Type pRequest->m_fileName = Utf2T(pszFileName);
pRequest->m_fileSize = pFile->size_;
pRequest->m_bRecv = !F.pMsg->is_outgoing_;
- pRequest->m_hContact = GetRealContact(F.pUser);
+ pRequest->m_hContact = GetRealContact(F.pUser, F.pMsg->message_thread_id_);
if (mir_strlen(pszCaption))
F.szBody += pszCaption;
@@ -460,14 +541,15 @@ bool CTelegramProto::GetMessageFile(const EmbeddedFile &F, TG_FILE_REQUEST::Type char szReplyId[100];
DB::EventInfo dbei(db_event_getById(m_szModuleName, F.pszId));
- dbei.flags = DBEF_TEMPORARY;
- dbei.timestamp = F.pMsg->date_;
+ dbei.bTemporary = true;
dbei.szId = F.pszId;
dbei.szUserId = F.pszUser;
+ if (F.pMsg->date_)
+ dbei.iTimestamp = F.pMsg->date_;
if (F.pMsg->is_outgoing_)
- dbei.flags |= DBEF_SENT;
+ dbei.bSent = dbei.bRead = true;
if (!F.pUser->bInited || F.bRead)
- dbei.flags |= DBEF_READ;
+ dbei.bRead = true;
if (auto iReplyId = getReplyId(F.pMsg->reply_to_.get())) {
_i64toa(iReplyId, szReplyId, 10);
dbei.szReplyId = szReplyId;
@@ -476,6 +558,7 @@ bool CTelegramProto::GetMessageFile(const EmbeddedFile &F, TG_FILE_REQUEST::Type if (dbei) {
if (!Ignore_IsIgnored(pRequest->m_hContact, IGNOREEVENT_FILE)) {
DB::FILE_BLOB blob(dbei);
+ blob.setDescr(Utf2T(pszCaption));
OnReceiveOfflineFile(dbei, blob);
blob.write(dbei);
db_event_edit(dbei.getEvent(), &dbei, true);
@@ -587,8 +670,10 @@ CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg wszNick = Utf2T(p->sender_name_.c_str());
break;
case TD::messageOriginChannel::ID:
- if (auto *p = FindChat(((TD::messageOriginChannel *)pForward->origin_.get())->chat_id_))
- wszNick = p->getDisplayName();
+ if (auto *p = FindChat(((TD::messageOriginChannel *)pForward->origin_.get())->chat_id_)) {
+ auto str = p->getDisplayName();
+ wszNick.Format(L"[url=https://t.me/%s]%s[/url]", str.c_str(), str.c_str());
+ }
break;
default:
wszNick = TranslateT("Unknown");
|