diff --git a/Telegram/PrepareWin.bat b/Telegram/PrepareWin.bat index 7fec83b31..c832556d5 100644 --- a/Telegram/PrepareWin.bat +++ b/Telegram/PrepareWin.bat @@ -1,10 +1,10 @@ @echo OFF set "AppVersionStrMajor=0.8" -set "AppVersion=8055" -set "AppVersionStrSmall=0.8.55" -set "AppVersionStr=0.8.55" -set "AppVersionStrFull=0.8.55.0" +set "AppVersion=8056" +set "AppVersionStrSmall=0.8.56" +set "AppVersionStr=0.8.56" +set "AppVersionStrFull=0.8.56.0" set "DevChannel=0" if %DevChannel% neq 0 goto preparedev diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index be5ffa269..cb1abb828 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -491,6 +491,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_report_spam" = "Report Spam"; +"lng_report_spam_hide" = "Hide"; +"lng_report_spam_thanks" = "Thank you for your report!"; +"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment. {more_info}"; +"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment. {more_info}"; +"lng_cant_more_info" = "More info »"; + "lng_send_button" = "Send"; "lng_message_ph" = "Write a message.."; "lng_record_cancel" = "Release outside this field to cancel"; @@ -501,6 +508,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "What can this bot do?"; "lng_unblock_button" = "Unblock"; +"lng_open_this_link" = "Open this link?"; +"lng_open_link" = "Open"; + "lng_bot_start" = "Start"; "lng_bot_choose_group" = "Choose Group"; "lng_bot_no_groups" = "You have no groups"; @@ -657,7 +667,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}"; "lng_new_version_minor" = "— Bug fixes and other minor improvements"; -"lng_new_version_text" = "— Include muted chats in unread count in Settings\n— Shared links overview and search in shared media\n— Preview when sending links to GIF animations and PDF files"; +"lng_new_version_text" = "— Spam report buttons in new chats\n— Other fixes and improvements\n— OS X 10.8 notifications fixed"; "lng_menu_insert_unicode" = "Insert Unicode control character"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 5b617f0ed..0ba857233 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -1106,7 +1106,34 @@ textRectMargins: margins(-2px, -1px, -2px, -1px); taMsgField: flatTextarea(taDefFlat) { font: msgFont; } -maxFieldHeight: 243px; +maxFieldHeight: 220px; +// historyMinHeight: 56px; + +reportSpamHide: flatButton(topBarButton) { + height: 46px; + + textTop: 15px; + overTextTop: 15px; + downTextTop: 16px; + + bgColor: transparent; + overBgColor: transparent; + downBgColor: transparent; +} +reportSpamButton: flatButton(reportSpamHide) { + textTop: 6px; + overTextTop: 6px; + downTextTop: 7px; + + width: -50px; + height: 30px; + + bgColor: #888; + overBgColor: #7b7b7b; + downBgColor: #7b7b7b; +} +reportSpamSeparator: 30px; +reportSpamBg: #fffffff0; newMsgSound: ':/gui/art/newmsg.wav'; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index c2f0f5e0a..00852611c 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -423,6 +423,10 @@ namespace App { data->setBotInfoVersion(-1); } data->contact = (flags & (MTPDuser_flag_contact | MTPDuser_flag_mutual_contact)) ? 1 : (data->phone.isEmpty() ? -1 : 0); + if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsNoButton) != dbiprsNoButton) { + cRefReportSpamStatuses().insert(data->id, dbiprsNoButton); + Local::writeReportSpamStatuses(); + } if ((flags & MTPDuser_flag_self) && ::self != data) { ::self = data; if (App::wnd()) App::wnd()->updateGlobalMenu(); @@ -568,10 +572,17 @@ namespace App { int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); chat->cankick = ChatData::CanKick(); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { - UserData *user = App::userLoaded(i->c_chatParticipant().vuser_id.v); + if (i->type() != mtpc_chatParticipant) continue; + + const MTPDchatParticipant &p(i->c_chatParticipant()); + //if (p.vuser_id.v == MTP::authedId()) { + // chat->inviter = p.vinviter_id.v; // we use inviter only from service msgs + // chat->inviteDate = p.vdate.v; + //} + UserData *user = App::userLoaded(p.vuser_id.v); if (user) { chat->participants[user] = pversion; - if (i->c_chatParticipant().vinviter_id.v == MTP::authedId()) { + if (p.vinviter_id.v == MTP::authedId()) { chat->cankick[user] = true; } } else { @@ -621,6 +632,10 @@ namespace App { ChatData *chat = App::chat(d.vchat_id.v); if (chat->version <= d.vversion.v && chat->count >= 0) { chat->version = d.vversion.v; + //if (d.vuser_id.v == MTP::authedId()) { + // chat->inviter = d.vinviter_id.v; // we use inviter only from service msgs + // chat->inviteDate = unixtime(); // no event date here :( + //} UserData *user = App::userLoaded(d.vuser_id.v); if (user) { if (chat->participants.isEmpty() && chat->count) { @@ -713,7 +728,7 @@ namespace App { bool hasLinks = m.has_entities() && !m.ventities.c_vector().v.isEmpty(); if ((hasLinks && !existing->hasTextLinks()) || (!hasLinks && existing->textHasLinks())) { existing->setText(qs(m.vmessage), m.has_entities() ? linksFromMTP(m.ventities.c_vector().v) : LinksInText()); - existing->initDimensions(0); + existing->initDimensions(); if (App::main()) App::main()->itemResized(existing); if (existing->hasTextLinks()) { existing->history()->addToOverview(existing, OverviewLinks); @@ -873,6 +888,10 @@ namespace App { switch (myLink.type()) { case mtpc_contactLinkContact: user->contact = 1; + if (user->contact == 1 && cReportSpamStatuses().value(user->id, dbiprsNoButton) != dbiprsNoButton) { + cRefReportSpamStatuses().insert(user->id, dbiprsNoButton); + Local::writeReportSpamStatuses(); + } break; case mtpc_contactLinkHasPhone: user->contact = 0; @@ -1768,6 +1787,7 @@ namespace App { cSetStickerSets(StickerSets()); cSetStickerSetsOrder(StickerSetsOrder()); cSetLastStickersUpdate(0); + cSetReportSpamStatuses(ReportSpamStatuses()); ::videoItems.clear(); ::audioItems.clear(); ::documentItems.clear(); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 6e92bb2be..6db0b553b 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -679,8 +679,10 @@ void Application::checkMapVersion() { QString versionFeatures; if (cDevVersion() && Local::oldMapVersion() < 8054) { versionFeatures = QString::fromUtf8("\xe2\x80\x94 Preview when sending links to GIF animations and PDF files\n\xe2\x80\x94 Full date and time shown when mouse over message timestamp");// .replace('@', qsl("@") + QChar(0x200D)); - } else if (!cDevVersion() && Local::oldMapVersion() < 8055) { + } else if (Local::oldMapVersion() < 8056) { versionFeatures = lang(lng_new_version_text).trimmed(); + } else { + versionFeatures = lang(lng_new_version_minor).trimmed(); } if (!versionFeatures.isEmpty()) { versionFeatures = lng_new_version_wrap(lt_version, QString::fromStdWString(AppVersionStr), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog")); diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp index bd4ed0d01..c601cfa97 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.cpp +++ b/Telegram/SourceFiles/boxes/confirmbox.cpp @@ -49,7 +49,7 @@ void ConfirmBox::init(const QString &text) { _text.setText(st::boxFont, text, (_infoMsg ? _confirmBoxTextOptions : _textPlainOptions)); _textWidth = st::boxWidth - st::boxPadding.left() - st::boxPadding.right(); - _textHeight = _text.countHeight(_textWidth); + _textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxFont->height); setMaxHeight(st::boxPadding.top() + _textHeight + st::boxPadding.bottom() + (_infoMsg ? _close.height() : _confirm.height())); if (_infoMsg) { @@ -171,7 +171,7 @@ void ConfirmBox::paintEvent(QPaintEvent *e) { // draw box title / text p.setFont(st::boxFont->f); p.setPen(st::black->p); - _text.draw(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, (_text.maxWidth() < width()) ? style::al_center : style::al_left); + _text.drawElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, 16, (_text.maxWidth() < width()) ? style::al_center : style::al_left); } void ConfirmBox::resizeEvent(QResizeEvent *e) { @@ -182,3 +182,16 @@ void ConfirmBox::resizeEvent(QResizeEvent *e) { _cancel.move(0, st::boxPadding.top() + _textHeight + st::boxPadding.bottom()); } } + +ConfirmLinkBox::ConfirmLinkBox(const QString &url) : ConfirmBox(lang(lng_open_this_link) + qsl("\n\n") + url, lang(lng_open_link)), _url(url) { + connect(this, SIGNAL(confirmed()), this, SLOT(onOpenLink())); +} + +void ConfirmLinkBox::onOpenLink() { + if (reMailStart().match(_url).hasMatch()) { + EmailLink(_url).onClick(Qt::LeftButton); + } else { + TextLink(_url).onClick(Qt::LeftButton); + } + App::wnd()->hideLayer(); +} diff --git a/Telegram/SourceFiles/boxes/confirmbox.h b/Telegram/SourceFiles/boxes/confirmbox.h index 1a54c33ac..101e27d3c 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.h +++ b/Telegram/SourceFiles/boxes/confirmbox.h @@ -67,3 +67,20 @@ private: QPoint _lastMousePos; TextLinkPtr _myLink; }; + +class ConfirmLinkBox : public ConfirmBox { + Q_OBJECT + +public: + + ConfirmLinkBox(const QString &url); + +public slots: + + void onOpenLink(); + +private: + + QString _url; + +}; diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 8e2530ab0..cd2253614 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -1318,7 +1318,7 @@ void CreateGroupBox::created(const MTPUpdates &updates) { } bool CreateGroupBox::failed(const RPCError &error) { - if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; + if (mtpIsFlood(error)) return false; _createRequestId = 0; if (error.type() == "NO_CHAT_TITLE") { @@ -1327,6 +1327,10 @@ bool CreateGroupBox::failed(const RPCError &error) { } else if (error.type() == "USERS_TOO_FEW") { emit closed(); return true; + } else if (error.type() == "PEER_FLOOD") { + emit closed(); + App::wnd()->showLayer(new ConfirmBox(lng_cant_invite_not_contact(lt_more_info, textcmdLink(qsl("https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts"), lang(lng_cant_more_info)))), true); + return true; } return false; } diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 06fe080f3..9dfc7e65a 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org */ #pragma once -static const int32 AppVersion = 8055; -static const wchar_t *AppVersionStr = L"0.8.55"; +static const int32 AppVersion = 8056; +static const wchar_t *AppVersionStr = L"0.8.56"; static const bool DevVersion = false; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index c5e439205..5607d9f05 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -838,7 +838,6 @@ void DialogsListWidget::peopleReceived(const QString &query, const QVector &contacts) { - cSetContactsReceived(true); for (QVector::const_iterator i = contacts.cbegin(), e = contacts.cend(); i != e; ++i) { int32 uid = i->c_contact().vuser_id.v; addNewContact(uid); @@ -1811,11 +1810,13 @@ void DialogsWidget::loadDialogs() { } void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &contacts) { + cSetContactsReceived(true); if (contacts.type() == mtpc_contacts_contacts) { const MTPDcontacts_contacts &d(contacts.c_contacts_contacts()); App::feedUsers(d.vusers); list.contactsReceived(d.vcontacts.c_vector().v); } + if (App::main()) App::main()->contactsReceived(); } bool DialogsWidget::contactsFailed(const RPCError &error) { diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index a27ad2118..6c1779987 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -21,6 +21,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "lang.h" #include "pspecific.h" +#include "boxes/confirmbox.h" +#include "window.h" #include @@ -60,6 +62,10 @@ const QRegularExpression &reMailName() { return _reMailName; } +const QRegularExpression &reMailStart() { + return _reMailStart; +} + const QRegularExpression &reHashtag() { return _reHashtag; } @@ -336,9 +342,16 @@ public: createBlock(); - QString lnkUrl = QString(start + waitingLink->offset, waitingLink->length), lnkText; int32 fullDisplayed; - getLinkData(lnkUrl, lnkText, fullDisplayed); + QString lnkUrl, lnkText; + if (waitingLink->type == LinkInTextCustomUrl) { + lnkUrl = waitingLink->text; + lnkText = QString(start + waitingLink->offset, waitingLink->length); + fullDisplayed = -5; + } else { + lnkUrl = QString(start + waitingLink->offset, waitingLink->length); + getLinkData(lnkUrl, lnkText, fullDisplayed); + } links.push_back(TextLinkData(lnkUrl, fullDisplayed)); lnkIndex = 0x8000 + links.size(); @@ -617,7 +630,9 @@ public: _t->_links.resize(lnkIndex); const TextLinkData &data(links[lnkIndex - maxLnkIndex - 1]); TextLinkPtr lnk; - if (data.fullDisplayed < -3) { // bot command + if (data.fullDisplayed < -4) { // hidden link + lnk = TextLinkPtr(new CustomTextLink(data.url)); + } else if (data.fullDisplayed < -3) { // bot command lnk = TextLinkPtr(new BotCommandLink(data.url)); } else if (data.fullDisplayed < -2) { // mention if (options.flags & TextTwitterMentions) { @@ -664,7 +679,7 @@ private: TextLinkData(const QString &url = QString(), int32 fullDisplayed = 1) : url(url), fullDisplayed(fullDisplayed) { } QString url; - int32 fullDisplayed; // -4 - bot command, -3 - mention, -2 - hashtag, -1 - email + int32 fullDisplayed; // -5 - custom text link, -4 - bot command, -3 - mention, -2 - hashtag, -1 - email }; typedef QVector TextLinks; TextLinks links; @@ -820,6 +835,10 @@ void EmailLink::onClick(Qt::MouseButton button) const { } } +void CustomTextLink::onClick(Qt::MouseButton button) const { + App::wnd()->showLayer(new ConfirmLinkBox(text())); +} + void MentionLink::onClick(Qt::MouseButton button) const { if (button == Qt::LeftButton || button == Qt::MiddleButton) { App::openPeerByName(_tag.mid(1), true); diff --git a/Telegram/SourceFiles/gui/text.h b/Telegram/SourceFiles/gui/text.h index bfc3749f0..77342dba6 100644 --- a/Telegram/SourceFiles/gui/text.h +++ b/Telegram/SourceFiles/gui/text.h @@ -357,6 +357,14 @@ private: }; +class CustomTextLink : public TextLink { +public: + + CustomTextLink(const QString &url) : TextLink(url, false) { + } + void onClick(Qt::MouseButton button) const; +}; + class EmailLink : public ITextLink { TEXT_LINK_CLASS(EmailLink) @@ -603,6 +611,7 @@ const QSet &validProtocols(); const QSet &validTopDomains(); const QRegularExpression &reDomain(); const QRegularExpression &reMailName(); +const QRegularExpression &reMailStart(); const QRegularExpression &reHashtag(); const QRegularExpression &reBotCommand(); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index dc715f5ed..78515cc54 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -1547,8 +1547,9 @@ MsgId History::msgIdForRead() const { return result; } -int32 History::geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText) { - if (width != newWidth || dontRecountText) { +int32 History::geomResize(int32 newWidth, int32 *ytransform, HistoryItem *resizedItem) { + if (width != newWidth) resizedItem = 0; // recount all items + if (width != newWidth || resizedItem) { int32 y = 0; for (iterator i = begin(), e = end(); i != e; ++i) { HistoryBlock *block = *i; @@ -1557,7 +1558,7 @@ int32 History::geomResize(int32 newWidth, int32 *ytransform, bool dontRecountTex if (block->y != y) { block->y = y; } - y += block->geomResize(newWidth, ytransform, dontRecountText); + y += block->geomResize(newWidth, ytransform, resizedItem); if (updTransform) { *ytransform += block->y; ytransform = 0; @@ -1646,14 +1647,18 @@ void History::removeBlock(HistoryBlock *block) { delete block; } -int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText) { +int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, HistoryItem *resizedItem) { int32 y = 0; for (iterator i = begin(), e = end(); i != e; ++i) { HistoryItem *item = *i; bool updTransform = ytransform && (*ytransform >= item->y) && (*ytransform < item->y + item->height()); if (updTransform) *ytransform -= item->y; item->y = y; - y += item->resize(newWidth, dontRecountText); + if (!resizedItem || resizedItem == item) { + y += item->resize(newWidth); + } else { + y += item->height(); + } if (updTransform) { *ytransform += item->y; ytransform = 0; @@ -1939,7 +1944,7 @@ void HistoryPhoto::initDimensions(const HistoryItem *parent) { } } -int32 HistoryPhoto::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryPhoto::resize(int32 width, const HistoryItem *parent) { const HistoryReply *reply = toHistoryReply(parent); const HistoryForwarded *fwd = reply ? 0 : toHistoryForwarded(parent); @@ -2264,8 +2269,11 @@ QString formatSizeText(qint64 size) { qint64 sizeTenthMb = (size * 10 / (1024 * 1024)); return QString::number(sizeTenthMb / 10) + '.' + QString::number(sizeTenthMb % 10) + qsl(" MB"); } - qint64 sizeTenthKb = (size * 10 / 1024); - return QString::number(sizeTenthKb / 10) + '.' + QString::number(sizeTenthKb % 10) + qsl(" KB"); + if (size >= 1024) { + qint64 sizeTenthKb = (size * 10 / 1024); + return QString::number(sizeTenthKb / 10) + '.' + QString::number(sizeTenthKb % 10) + qsl(" KB"); + } + return QString::number(size) + qsl(" B"); } QString formatDownloadText(qint64 ready, qint64 total) { @@ -2275,11 +2283,15 @@ QString formatDownloadText(qint64 ready, qint64 total) { readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10); totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10); mb = qsl("MB"); - } else { + } else if (total >= 1024) { qint64 readyKb = (ready / 1024), totalKb = (total / 1024); readyStr = QString::number(readyKb); totalStr = QString::number(totalKb); mb = qsl("KB"); + } else { + readyStr = QString::number(ready); + totalStr = QString::number(total); + mb = qsl("B"); } return lng_save_downloaded(lt_ready, readyStr, lt_total, totalStr, lt_mb, mb); } @@ -2652,7 +2664,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i } } -int32 HistoryVideo::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryVideo::resize(int32 width, const HistoryItem *parent) { w = qMin(width, _maxw); if (_caption.isEmpty()) return _height; @@ -3386,7 +3398,7 @@ void HistoryDocument::updateFrom(const MTPMessageMedia &media) { } } -int32 HistoryDocument::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryDocument::resize(int32 width, const HistoryItem *parent) { w = qMin(width, _maxw); if (parent == animated.msg) { if (w > st::maxMediaSize) { @@ -3628,7 +3640,7 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected, } } -int32 HistorySticker::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistorySticker::resize(int32 width, const HistoryItem *parent) { w = qMin(width, _maxw); lastw = width; return _height; @@ -4325,7 +4337,7 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected, p.restore(); } -int32 HistoryWebPage::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryWebPage::resize(int32 width, const HistoryItem *parent) { if (data->pendingTill) { w = width; _height = _minh; @@ -5124,7 +5136,7 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte } } -int32 HistoryImageLink::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryImageLink::resize(int32 width, const HistoryItem *parent) { const HistoryReply *reply = toHistoryReply(parent); const HistoryForwarded *fwd = toHistoryForwarded(parent); @@ -5410,7 +5422,7 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc) { _media->regItem(this); } -void HistoryMessage::initDimensions(const HistoryItem *parent) { +void HistoryMessage::initDimensions() { if (justMedia()) { _media->initDimensions(this); _maxw = _media->maxWidth(); @@ -5493,7 +5505,7 @@ void HistoryMessage::setMedia(const MTPMessageMedia *media) { _textWidth = 0; _textHeight = 0; } - initDimensions(0); + initDimensions(); if (App::main()) App::main()->itemResized(this); } @@ -5630,15 +5642,13 @@ void HistoryMessage::drawMessageText(QPainter &p, const QRect &trect, uint32 sel textstyleRestore(); } -int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryMessage::resize(int32 width) { if (width < st::msgMinWidth) return _height; width -= st::msgMargin.left() + st::msgMargin.right(); if (justMedia()) { - _height = _media->resize(width, dontRecountText, this); + _height = _media->resize(width, this); } else { - if (dontRecountText && !_media) return _height; - if (width < st::msgPadding.left() + st::msgPadding.right() + 1) { width = st::msgPadding.left() + st::msgPadding.right() + 1; } else if (width > st::msgMaxWidth) { @@ -5651,10 +5661,10 @@ int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryIte } if (width >= _maxw) { _height = _minh; - if (_media) _media->resize(_maxw - st::msgPadding.left() - st::msgPadding.right(), dontRecountText, this); + if (_media) _media->resize(_maxw - st::msgPadding.left() - st::msgPadding.right(), this); } else { _height = _textHeight; - if (_media && _media->isDisplayed()) _height += st::msgPadding.bottom() + _media->resize(nwidth, dontRecountText, this); + if (_media && _media->isDisplayed()) _height += st::msgPadding.bottom() + _media->resize(nwidth, this); } if (displayFromName()) { _height += st::msgNameFont->height; @@ -5864,8 +5874,8 @@ QString HistoryForwarded::selectedText(uint32 selection) const { return result; } -void HistoryForwarded::initDimensions(const HistoryItem *parent) { - HistoryMessage::initDimensions(parent); +void HistoryForwarded::initDimensions() { + HistoryMessage::initDimensions(); fwdNameUpdated(); } @@ -5908,11 +5918,10 @@ void HistoryForwarded::drawMessageText(QPainter &p, const QRect &trect, uint32 s HistoryMessage::drawMessageText(p, realtrect, selection); } -int32 HistoryForwarded::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { - HistoryMessage::resize(width, dontRecountText, parent); - if (!justMedia() && (_media || !dontRecountText)) { - _height += st::msgServiceNameFont->height; - } +int32 HistoryForwarded::resize(int32 width) { + HistoryMessage::resize(width); + + _height += st::msgServiceNameFont->height; return _height; } @@ -6064,11 +6073,11 @@ QString HistoryReply::selectedText(uint32 selection) const { return result; } -void HistoryReply::initDimensions(const HistoryItem *parent) { +void HistoryReply::initDimensions() { if (!replyToMsg) { _maxReplyWidth = st::msgReplyBarSkip + st::msgDateFont->m.width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message)) + st::msgPadding.left() + st::msgPadding.right(); } - HistoryMessage::initDimensions(parent); + HistoryMessage::initDimensions(); if (replyToMsg) { replyToNameUpdated(); } else if (!justMedia()) { @@ -6211,11 +6220,10 @@ void HistoryReply::drawMessageText(QPainter &p, const QRect &trect, uint32 selec HistoryMessage::drawMessageText(p, realtrect, selection); } -int32 HistoryReply::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { - HistoryMessage::resize(width, dontRecountText, parent); - if (!justMedia() && (_media || !dontRecountText)) { - _height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - } +int32 HistoryReply::resize(int32 width) { + HistoryMessage::resize(width); + + _height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); return _height; } @@ -6357,6 +6365,11 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { UserData *u = App::user(peerFromUser(d.vuser_id)); second = TextLinkPtr(new PeerLink(u)); text = lng_action_add_user(lt_from, from, lt_user, textcmdLink(2, u->name)); + if (d.vuser_id.v == MTP::authedId() && unread()) { + if (history()->peer->chat && !history()->peer->asChat()->inviterForSpamReport && !_from->chat) { + history()->peer->asChat()->inviterForSpamReport = App::userFromPeer(_from->id); + } + } } } break; @@ -6374,6 +6387,11 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionChatCreate: { const MTPDmessageActionChatCreate &d(action.c_messageActionChatCreate()); text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle))); + if (unread()) { + if (history()->peer->chat && !history()->peer->asChat()->inviterForSpamReport && !_from->chat && App::userFromPeer(_from->id) != MTP::authedId()) { + history()->peer->asChat()->inviterForSpamReport = App::userFromPeer(_from->id); + } + } } break; case mtpc_messageActionChannelCreate: { @@ -6437,10 +6455,10 @@ HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgI { } -void HistoryServiceMsg::initDimensions(const HistoryItem *parent) { +void HistoryServiceMsg::initDimensions() { _maxw = _text.maxWidth() + st::msgServicePadding.left() + st::msgServicePadding.right(); _minh = _text.minHeight(); - if (_media) _media->initDimensions(); + if (_media) _media->initDimensions(this); } QString HistoryServiceMsg::selectedText(uint32 selection) const { @@ -6503,9 +6521,7 @@ void HistoryServiceMsg::draw(QPainter &p, uint32 selection) const { textstyleRestore(); } -int32 HistoryServiceMsg::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { - if (dontRecountText) return _height; - +int32 HistoryServiceMsg::resize(int32 width) { width -= st::msgServiceMargin.left() + st::msgServiceMargin.left(); // two small margins if (width < st::msgServicePadding.left() + st::msgServicePadding.right() + 1) width = st::msgServicePadding.left() + st::msgServicePadding.right() + 1; @@ -6521,7 +6537,7 @@ int32 HistoryServiceMsg::resize(int32 width, bool dontRecountText, const History } _height += st::msgServicePadding.top() + st::msgServicePadding.bottom() + st::msgServiceMargin.top() + st::msgServiceMargin.bottom(); if (_media) { - _height += st::msgServiceMargin.top() + _media->resize(_media->currentWidth()); + _height += st::msgServiceMargin.top() + _media->resize(_media->currentWidth(), this); } return _height; } @@ -6607,7 +6623,7 @@ HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 initDimensions(); } -void HistoryUnreadBar::initDimensions(const HistoryItem *parent) { +void HistoryUnreadBar::initDimensions() { _maxw = st::msgPadding.left() + st::msgPadding.right() + 1; _minh = st::unreadBarHeight; } @@ -6626,7 +6642,7 @@ void HistoryUnreadBar::draw(QPainter &p, uint32 selection) const { p.drawText(QRect(0, 0, _history->width, st::unreadBarHeight - st::lineWidth), text, style::al_center); } -int32 HistoryUnreadBar::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { +int32 HistoryUnreadBar::resize(int32 width) { _height = st::unreadBarHeight; return _height; } diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 5ee85b99d..0c41f3304 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -220,7 +220,7 @@ struct History : public QList { MsgId maxMsgId() const; MsgId msgIdForRead() const; - int32 geomResize(int32 newWidth, int32 *ytransform = 0, bool dontRecountText = false); // return new size + int32 geomResize(int32 newWidth, int32 *ytransform = 0, HistoryItem *resizedItem = 0); // return new size int32 width, height, msgCount, unreadCount; int32 inboxReadBefore, outboxReadBefore; HistoryItem *showFrom; @@ -607,7 +607,7 @@ struct HistoryBlock : public QVector { } void removeItem(HistoryItem *item); - int32 geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText); // return new size + int32 geomResize(int32 newWidth, int32 *ytransform, HistoryItem *resizedItem); // return new size int32 y, height; History *history; }; @@ -618,9 +618,6 @@ public: HistoryElem() : _height(0), _maxw(0) { } - virtual void initDimensions(const HistoryItem *parent = 0) = 0; - virtual int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0) = 0; // return new height - int32 height() const { return _height; } @@ -676,7 +673,10 @@ public: UnreadBarType }; + virtual void initDimensions() = 0; + virtual int32 resize(int32 width) = 0; // return new height virtual void draw(QPainter &p, uint32 selection) const = 0; + History *history() { return _history; } @@ -873,7 +873,8 @@ public: virtual int32 countHeight(const HistoryItem *parent, int32 width = -1) const { return height(); } - virtual int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0) { + virtual void initDimensions(const HistoryItem *parent) = 0; + virtual int32 resize(int32 width, const HistoryItem *parent) { // return new height w = qMin(width, _maxw); return _height; } @@ -928,7 +929,7 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypePhoto; } @@ -978,7 +979,7 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypeVideo; } @@ -1058,7 +1059,7 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypeDocument; } @@ -1109,7 +1110,7 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypeSticker; } @@ -1174,7 +1175,7 @@ public: bool isDisplayed() const { return !data->pendingTill; } - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypeWebPage; } @@ -1278,7 +1279,7 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width, const HistoryItem *parent); HistoryMediaType type() const { return MediaTypeImageLink; } @@ -1311,7 +1312,7 @@ public: void initMedia(const MTPMessageMedia *media, QString ¤tText); void initMediaFromText(QString ¤tText); void initMediaFromDocument(DocumentData *doc); - void initDimensions(const HistoryItem *parent = 0); + void initDimensions(); void fromNameUpdated() const; bool justMedia() const { @@ -1323,7 +1324,7 @@ public: void draw(QPainter &p, uint32 selection) const; virtual void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const; @@ -1397,13 +1398,13 @@ public: HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg); HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg); - void initDimensions(const HistoryItem *parent = 0); + void initDimensions(); void fwdNameUpdated() const; void draw(QPainter &p, uint32 selection) const; void drawForwardedFrom(QPainter &p, int32 x, int32 y, int32 w, bool selected) const; void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const; void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const; @@ -1441,7 +1442,7 @@ public: HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg); HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc); - void initDimensions(const HistoryItem *parent = 0); + void initDimensions(); bool updateReplyTo(bool force = false); void replyToNameUpdated() const; @@ -1456,7 +1457,7 @@ public: void draw(QPainter &p, uint32 selection) const; void drawReplyTo(QPainter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const; void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const; void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const; @@ -1494,10 +1495,10 @@ public: HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg); HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0); - void initDimensions(const HistoryItem *parent = 0); + void initDimensions(); void draw(QPainter &p, uint32 selection) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; @@ -1564,12 +1565,12 @@ public: HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date); - void initDimensions(const HistoryItem *parent = 0); + void initDimensions(); void setCount(int32 count); void draw(QPainter &p, uint32 selection) const; - int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); + int32 resize(int32 width); void drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const; QString notificationText() const; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 42ecf97ba..211cef068 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1065,7 +1065,7 @@ void HistoryList::keyPressEvent(QKeyEvent *e) { } } -int32 HistoryList::recountHeight(bool dontRecountText) { +int32 HistoryList::recountHeight(HistoryItem *resizedItem) { int32 st = hist->lastScrollTop; int32 ph = scrollArea->height(), minadd = 0; @@ -1075,7 +1075,7 @@ int32 HistoryList::recountHeight(bool dontRecountText) { } if (wasYSkip < minadd) wasYSkip = minadd; - hist->geomResize(scrollArea->width(), &st, dontRecountText); + hist->geomResize(scrollArea->width(), &st, resizedItem); updateBotInfo(false); if (botInfo && !botInfo->text.isEmpty()) { int32 tw = scrollArea->width() - st::msgMargin.left() - st::msgMargin.right(); @@ -1654,6 +1654,52 @@ void MessageField::focusInEvent(QFocusEvent *e) { emit focused(); } +ReportSpamPanel::ReportSpamPanel(HistoryWidget *parent) : TWidget(parent), +_report(this, lang(lng_report_spam), st::reportSpamHide), +_hide(this, lang(lng_report_spam_hide), st::reportSpamHide), +_clear(this, lang(lng_profile_delete_conversation)) { + resize(parent->width(), _hide.height() + st::titleShadow); + + connect(&_report, SIGNAL(clicked()), this, SIGNAL(reportClicked())); + connect(&_hide, SIGNAL(clicked()), this, SIGNAL(hideClicked())); + connect(&_clear, SIGNAL(clicked()), this, SIGNAL(clearClicked())); + + _clear.hide(); +} + +void ReportSpamPanel::resizeEvent(QResizeEvent *e) { + _report.resize(width() - (_hide.width() + st::reportSpamSeparator) * 2, _report.height()); + _report.moveToLeft(_hide.width() + st::reportSpamSeparator, 0, width()); + _hide.moveToRight(0, 0, width()); + _clear.move((width() - _clear.width()) / 2, height() - _clear.height() - ((height() - st::msgFont->height - _clear.height()) / 2)); +} + +void ReportSpamPanel::paintEvent(QPaintEvent *e) { + Painter p(this); + p.fillRect(QRect(0, 0, width(), height() - st::titleShadow), st::reportSpamBg->b); + if (cWideMode()) { + p.fillRect(st::titleShadow, height() - st::titleShadow, width() - st::titleShadow, st::titleShadow, st::titleShadowColor->b); + } else { + p.fillRect(0, height() - st::titleShadow, width(), st::titleShadow, st::titleShadowColor->b); + } + if (!_clear.isHidden()) { + p.setPen(st::black->p); + p.setFont(st::msgFont->f); + p.drawText(QRect(_report.x(), (_clear.y() - st::msgFont->height) / 2, _report.width(), st::msgFont->height), lang(lng_report_spam_thanks), style::al_top); + } +} + +void ReportSpamPanel::setReported(bool reported) { + if (reported) { + _report.hide(); + _clear.show(); + } else { + _report.show(); + _clear.hide(); + } + update(); +} + BotKeyboard::BotKeyboard() : _height(0), _maxOuterHeight(0), _maximizeSize(false), _singleUse(false), _forceReply(false), _sel(-1), _down(-1), _hoverAnim(animFunc(this, &BotKeyboard::hoverStep)), _st(&st::botKbButton) { setGeometry(0, 0, _st->margin, _st->margin); @@ -2217,6 +2263,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _replyTo(0) , _replyToNameVersion(0) , _replyForwardPreviewCancel(this, st::replyCancel) +, _reportSpamStatus(dbiprsUnknown) , _previewData(0) , _previewRequest(0) , _previewCancelled(false) @@ -2225,6 +2272,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _stickersUpdateRequest(0) , _peer(0) , _channel(NoChannel) +, _clearPeer(0) , _showAtMsgId(0) , _preloadRequest(0), _preloadDownRequest(0) , _delayedShowAtMsgId(-1) @@ -2236,10 +2284,12 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _histInited(false) , _toHistoryEnd(this, st::historyToEnd) , _attachMention(this) +, _reportSpamPanel(this) , _send(this, lang(lng_send_button), st::btnSend) , _unblock(this, lang(lng_unblock_button), st::btnUnblock) , _botStart(this, lang(lng_bot_start), st::btnSend) , _unblockRequest(0) +, _reportSpamRequest(0) , _attachDocument(this, st::btnAttachDocument) , _attachPhoto(this, st::btnAttachPhoto) , _attachEmoji(this, st::btnAttachEmoji) @@ -2279,6 +2329,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) setAcceptDrops(true); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); + connect(&_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked())); + connect(&_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide())); + connect(&_reportSpamPanel, SIGNAL(clearClicked()), this, SLOT(onReportSpamClear())); connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd())); connect(&_replyForwardPreviewCancel, SIGNAL(clicked()), this, SLOT(onReplyForwardPreviewCancel())); connect(&_send, SIGNAL(clicked()), this, SLOT(onSend())); @@ -2348,6 +2401,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) _unblock.hide(); _botStart.hide(); + _reportSpamPanel.move(0, 0); + _reportSpamPanel.hide(); + _attachDocument.hide(); _attachPhoto.hide(); _attachEmoji.hide(); @@ -2818,7 +2874,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) { _channel = _peer ? peerToChannel(_peer->id) : NoChannel; _canSendMessages = canSendMessages(_peer); - _unblockRequest = 0; + _unblockRequest = _reportSpamRequest = 0; _titlePeerText = QString(); _titlePeerTextWidth = 0; @@ -2928,8 +2984,74 @@ void HistoryWidget::clearAllLoadRequests() { _preloadRequest = _preloadDownRequest = _firstLoadRequest = 0; } +void HistoryWidget::contactsReceived() { + if (!_peer) return; + updateReportSpamStatus(); + updateControlsVisibility(); +} + +void HistoryWidget::updateReportSpamStatus() { + if (!_peer || (_peer->isUser() && (peerToUser(_peer->id) == MTP::authedId() || isNotificationsUser(_peer->id) || isServiceUser(_peer->id) || _peer->asUser()->botInfo))) { + _reportSpamStatus = dbiprsNoButton; + return; + } else { + ReportSpamStatuses::const_iterator i = cReportSpamStatuses().constFind(_peer->id); + if (i != cReportSpamStatuses().cend()) { + _reportSpamStatus = i.value(); + _reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent); + return; + } + } + if ((!_history->loadedAtTop() && (_history->size() < 2 || (_history->size() == 2 && _history->at(1)->size() < 2))) || !cContactsReceived() || _firstLoadRequest) { + _reportSpamStatus = dbiprsUnknown; + } else if (_peer->isUser()) { + if (_peer->asUser()->contact > 0) { + _reportSpamStatus = dbiprsNoButton; + } else { + bool anyFound = false, outFound = false; + for (int32 i = 0, l = _history->size(); i < l; ++i) { + for (int32 j = 0, c = _history->at(i)->size(); j < c; ++j) { + anyFound = true; + if (_history->at(i)->at(j)->out()) { + outFound = true; + break; + } + } + } + if (anyFound) { + if (outFound) { + _reportSpamStatus = dbiprsNoButton; + } else { + _reportSpamStatus = dbiprsShowButton; + } + } else { + _reportSpamStatus = dbiprsUnknown; + } + } + } else if (_peer->isChat()) { + if (_peer->asChat()->inviterForSpamReport > 0) { + UserData *user = App::userLoaded(_peer->asChat()->inviterForSpamReport); + if (user && user->contact > 0) { + _reportSpamStatus = dbiprsNoButton; + } else { + _reportSpamStatus = dbiprsShowButton; + } + } else { + _reportSpamStatus = dbiprsNoButton; + } + } else if (_peer->isChannel()) { + _reportSpamStatus = dbiprsUnknown; + } + if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsNoButton) { + _reportSpamPanel.setReported(false); + cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus); + Local::writeReportSpamStatuses(); + } +} + void HistoryWidget::updateControlsVisibility() { if (!_history || _showAnim.animating()) { + _reportSpamPanel.hide(); _scroll.hide(); _kbScroll.hide(); _send.hide(); @@ -2956,6 +3078,11 @@ void HistoryWidget::updateControlsVisibility() { } else { _scroll.show(); } + if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsReportSent) { + _reportSpamPanel.show(); + } else { + _reportSpamPanel.hide(); + } if (_canSendMessages) { checkMentionDropdown(); if (isBlocked()) { @@ -3184,6 +3311,10 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe addMessagesToFront(*histList); _preloadRequest = 0; onListScroll(); + if (_reportSpamStatus == dbiprsUnknown) { + updateReportSpamStatus(); + if (_reportSpamStatus != dbiprsUnknown) updateControlsVisibility(); + } } else if (_preloadDownRequest == requestId) { addMessagesToBack(*histList); _preloadDownRequest = 0; @@ -3437,10 +3568,18 @@ void HistoryWidget::unblockDone(PeerData *peer, const MTPBool &result) { bool HistoryWidget::unblockFail(const RPCError &error) { if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; -// _unblockRequest = 0; + + _unblockRequest = 0; return false; } +void HistoryWidget::blockDone(PeerData *peer, const MTPBool &result) { + if (!peer->isUser()) return; + + peer->asUser()->blocked = UserIsBlocked; + emit App::main()->peerUpdated(peer); +} + void HistoryWidget::onBotStart() { if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) { updateControlsVisibility(); @@ -3494,14 +3633,15 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const flags |= MTPDmessage::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } + bool fromChannelName = p->isChannel(); if (fromChannelName) { sendFlags |= MTPmessages_SendMessage_flag_broadcast; } else { flags |= MTPDmessage::flag_from_id; } - h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(peer), MTPint(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities)); - h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, h->sendRequestId); + h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(peer), MTPPeer(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities, MTPint())); + h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, h->sendRequestId); App::historyRegRandom(randomId, newId); @@ -3533,6 +3673,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo App::main()->topBar()->startAnim(); _scroll.hide(); _kbScroll.hide(); + _reportSpamPanel.hide(); _toHistoryEnd.hide(); _attachDocument.hide(); _attachPhoto.hide(); @@ -3581,6 +3722,7 @@ bool HistoryWidget::showStep(float64 ms) { } void HistoryWidget::doneShow() { + updateReportSpamStatus(); updateBotKeyboard(); updateControlsVisibility(); updateListSize(0, true); @@ -4403,12 +4545,12 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) { flags |= MTPDmessage::flag_from_id; } if (img.type == ToPreparePhoto) { - h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities)); + h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities, MTPint())); } else if (img.type == ToPrepareDocument) { - h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities)); + h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities, MTPint())); } else if (img.type == ToPrepareAudio) { flags |= MTPDmessage_flag_media_unread; - h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities)); + h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities, MTPint())); } if (_peer && img.peer == _peer->id) { @@ -4437,11 +4579,12 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, const MTPInputFile & if (replyTo) { sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } + bool fromChannelName = hist->peer->isChannel(); if (fromChannelName) { sendFlags |= MTPmessages_SendMessage_flag_broadcast; } - hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string("")), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string("")), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendPhotoFail, randomId), 0, 0, hist->sendRequestId); } } @@ -4481,11 +4624,12 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, const MTPInputFil if (replyTo) { sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } + bool fromChannelName = hist->peer->isChannel(); if (fromChannelName) { sendFlags |= MTPmessages_SendMessage_flag_broadcast; } - hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); } } } @@ -4509,11 +4653,12 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, const MTPInp if (replyTo) { sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } + bool fromChannelName = hist->peer->isChannel(); if (fromChannelName) { sendFlags |= MTPmessages_SendMessage_flag_broadcast; } - hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); } } } @@ -4535,11 +4680,12 @@ void HistoryWidget::onAudioUploaded(const FullMsgId &newId, const MTPInputFile & if (replyTo) { sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } + bool fromChannelName = hist->peer->isChannel(); if (fromChannelName) { sendFlags |= MTPmessages_SendMessage_flag_broadcast; } - hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedAudio(file, MTP_int(audio->duration), MTP_string(audio->mime)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedAudio(file, MTP_int(audio->duration), MTP_string(audio->mime)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); } } } @@ -4601,6 +4747,62 @@ void HistoryWidget::onAudioFailed(const FullMsgId &newId) { } } +void HistoryWidget::onReportSpamClicked() { + if (_reportSpamRequest) return; + + if (_peer->isUser()) MTP::send(MTPcontacts_Block(_peer->asUser()->inputUser), rpcDone(&HistoryWidget::blockDone, _peer), RPCFailHandlerPtr(), 0, 5); + _reportSpamRequest = MTP::send(MTPmessages_ReportSpam(_peer->input), rpcDone(&HistoryWidget::reportSpamDone, _peer), rpcFail(&HistoryWidget::reportSpamFail)); +} + +void HistoryWidget::reportSpamDone(PeerData *peer, const MTPBool &result, mtpRequestId req) { + if (req == _reportSpamRequest) { + _reportSpamRequest = 0; + } + if (peer) { + cRefReportSpamStatuses().insert(peer->id, dbiprsReportSent); + Local::writeReportSpamStatuses(); + } + _reportSpamStatus = dbiprsReportSent; + _reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent); +} + +bool HistoryWidget::reportSpamFail(const RPCError &error, mtpRequestId req) { + if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; + + if (req == _reportSpamRequest) { + _reportSpamRequest = 0; + } + return false; +} + +void HistoryWidget::onReportSpamHide() { + if (_peer) { + cRefReportSpamStatuses().insert(_peer->id, dbiprsNoButton); + Local::writeReportSpamStatuses(); + } + _reportSpamStatus = dbiprsNoButton; + updateControlsVisibility(); +} + +void HistoryWidget::onReportSpamClear() { + ConfirmBox *box = new ConfirmBox(_peer->isUser() ? lng_sure_delete_history(lt_contact, _peer->name) : lng_sure_delete_and_exit(lt_group, _peer->name)); + connect(box, SIGNAL(confirmed()), this, SLOT(onReportSpamClearSure())); + App::wnd()->showLayer(box); + _clearPeer = _peer; +} + +void HistoryWidget::onReportSpamClearSure() { + if (_clearPeer->isUser()) { + App::main()->deleteConversation(_clearPeer); + } else if (_clearPeer->isChat()) { + App::wnd()->hideLayer(); + App::main()->showDialogs(); + MTP::send(MTPmessages_DeleteChatUser(_clearPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _clearPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _clearPeer)); + } else if (_clearPeer->isChannel()) { // CHANNELS_UX + + } +} + void HistoryWidget::peerMessagesUpdated(PeerId peer) { if (_peer && _list && peer == _peer->id) { updateListSize(); @@ -4623,6 +4825,8 @@ void HistoryWidget::msgUpdated(PeerId peer, const HistoryItem *msg) { } void HistoryWidget::resizeEvent(QResizeEvent *e) { + _reportSpamPanel.resize(width(), _reportSpamPanel.height()); + int32 maxKeyboardHeight = int(st::maxFieldHeight) - _field.height(); _keyboard.resizeToWidth(width(), maxKeyboardHeight); @@ -4711,7 +4915,7 @@ MsgId HistoryWidget::replyToId() const { void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, HistoryItem *resizedItem, bool scrollToIt) { if (!_history || (initial && _histInited) || (!initial && !_histInited)) return; if (_firstLoadRequest) { - if (resizedItem) _list->recountHeight(true); + if (resizedItem) _list->recountHeight(resizedItem); return; // scrollTopMax etc are not working after recountHeight() } @@ -4741,7 +4945,7 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, if (!initial) { _history->lastScrollTop = _scroll.scrollTop(); } - int32 newSt = _list->recountHeight(!!resizedItem); + int32 newSt = _list->recountHeight(resizedItem); bool washidden = _scroll.isHidden(); if (washidden) { _scroll.show(); @@ -5036,7 +5240,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) { } _history->addToBackDocument(newId.msg, flags, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), sticker); - _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, _history->sendRequestId); + _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); App::main()->finishForwarding(_history); cancelReply(lastKeyboardUsed); @@ -5288,6 +5492,7 @@ void HistoryWidget::onFullPeerUpdated(PeerData *data) { updateControlsVisibility(); } checkMentionDropdown(); + updateReportSpamStatus(); int32 lh = _list->height(), st = _scroll.scrollTop(); _list->updateBotInfo(); newScrollTop = st + _list->height() - lh; diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 61759f3af..c01f486e6 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -63,7 +63,7 @@ public: void touchScrollUpdated(const QPoint &screenPos); QPoint mapMouseToItem(QPoint p, HistoryItem *item); - int32 recountHeight(bool dontRecountText); + int32 recountHeight(HistoryItem *resizedItem); void updateSize(); void updateMsg(const HistoryItem *msg); @@ -220,6 +220,32 @@ private: }; +class HistoryWidget; +class ReportSpamPanel : public TWidget { + Q_OBJECT + +public: + + ReportSpamPanel(HistoryWidget *parent); + + void resizeEvent(QResizeEvent *e); + void paintEvent(QPaintEvent *e); + + void setReported(bool reported); + +signals: + + void hideClicked(); + void reportClicked(); + void clearClicked(); + +private: + + FlatButton _report, _hide; + LinkButton _clear; + +}; + class BotKeyboard : public QWidget { Q_OBJECT @@ -490,6 +516,8 @@ public: void clearDelayedShowAt(); void clearAllLoadRequests(); + void contactsReceived(); + ~HistoryWidget(); signals: @@ -527,6 +555,11 @@ public slots: void onDocumentFailed(const FullMsgId &msgId); void onAudioFailed(const FullMsgId &msgId); + void onReportSpamClicked(); + void onReportSpamHide(); + void onReportSpamClear(); + void onReportSpamClearSure(); + void onListScroll(); void onHistoryToEnd(); void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1); @@ -597,6 +630,9 @@ private: void drawRecording(Painter &p); void updateField(); + DBIPeerReportSpamStatus _reportSpamStatus; + void updateReportSpamStatus(); + QString _previewLinks; WebPageData *_previewData; typedef QMap PreviewCache; @@ -617,8 +653,12 @@ private: void addMessagesToFront(const QVector &messages); void addMessagesToBack(const QVector &messages); + void reportSpamDone(PeerData *peer, const MTPBool &result, mtpRequestId request); + bool reportSpamFail(const RPCError &error, mtpRequestId request); + void unblockDone(PeerData *peer, const MTPBool &result); bool unblockFail(const RPCError &error); + void blockDone(PeerData *peer, const MTPBool &result); void countHistoryShowFrom(); @@ -639,7 +679,7 @@ private: bool canSendMessages(PeerData *peer); bool readyToForward(); - PeerData *_peer; + PeerData *_peer, *_clearPeer; // cache _peer in _clearPeer when showing clear history box ChannelId _channel; bool _canSendMessages; MsgId _showAtMsgId; @@ -664,8 +704,10 @@ private: bool isBlocked() const; bool updateCmdStartShown(); + ReportSpamPanel _reportSpamPanel; + FlatButton _send, _unblock, _botStart; - mtpRequestId _unblockRequest; + mtpRequestId _unblockRequest, _reportSpamRequest; IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide, _cmdStart; bool _cmdStartShown; MessageField _field; diff --git a/Telegram/SourceFiles/langs/lang_de.strings b/Telegram/SourceFiles/langs/lang_de.strings index 2bfd27567..44360ddbc 100644 --- a/Telegram/SourceFiles/langs/lang_de.strings +++ b/Telegram/SourceFiles/langs/lang_de.strings @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (Sticker)"; +"lng_report_spam" = "Spam melden"; +"lng_report_spam_hide" = "Schließen"; +"lng_report_spam_thanks" = "Danke für die Meldung!"; +"lng_cant_send_to_not_contact" = "Derzeit kannst du nur Personen schreiben, wenn ihr eure Nummern ausgetauscht habt. {more_info}"; +"lng_cant_invite_not_contact" = "Du kannst nur Personen hinzufügen, wenn ihr eure Nummern ausgetauscht habt. {more_info}"; +"lng_cant_more_info" = "Weitere Infos »"; + "lng_send_button" = "Senden"; "lng_message_ph" = "Schreibe deine Nachricht.."; "lng_record_cancel" = "Zum Abbrechen rausbewegen"; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "Was kann dieser Bot?"; "lng_unblock_button" = "Freigeben"; +"lng_open_this_link" = "Diesen Link öffnen?"; +"lng_open_link" = "Öffnen"; + "lng_bot_start" = "Starten"; "lng_bot_choose_group" = "Gruppe auswählen"; "lng_bot_no_groups" = "Du hast keine Gruppen"; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}"; "lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen"; -"lng_new_version_text" = "— Stummgeschaltete Chats können ab sofort optional mitgezählt werden (Einstellungen > Stummgeschaltete Chats mitzählen)\n— Übersicht der im Chat geteilten Links im Bereich 'Geteilte Medien'\n— GIF-Vorschau und PDF-Vorschau von Direktlinks (.pdf und .gif)"; +"lng_new_version_text" = "— Unerwünschte Nachrichten (Spam) in neuen Chats melden\n— Sonstige Fehlerbehungen und Verbesserungen\n— OS X 10.8 Benachrichtigungen funktionieren wieder"; "lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen"; diff --git a/Telegram/SourceFiles/langs/lang_es.strings b/Telegram/SourceFiles/langs/lang_es.strings index 47e93f526..73e7a462b 100644 --- a/Telegram/SourceFiles/langs/lang_es.strings +++ b/Telegram/SourceFiles/langs/lang_es.strings @@ -457,7 +457,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_media_video" = "Vídeo"; "lng_media_audio" = "Mensaje de voz"; -"lng_emoji_category0" = "Usados con frecuencia"; +"lng_emoji_category0" = "Uso frecuente"; "lng_emoji_category1" = "Personas"; "lng_emoji_category2" = "Naturaleza"; "lng_emoji_category3" = "Comida y bebida"; @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_report_spam" = "Reportar spam"; +"lng_report_spam_hide" = "Ocultar"; +"lng_report_spam_thanks" = "¡Gracias por tu reporte!"; +"lng_cant_send_to_not_contact" = "Por ahora, sólo puedes enviar mensajes\na contactos mutuos. {more_info}"; +"lng_cant_invite_not_contact" = "Por ahora, sólo puedes añadir contactos \nmutuos a grupos. {more_info}"; +"lng_cant_more_info" = "Más información »"; + "lng_send_button" = "Enviar"; "lng_message_ph" = "Escribir un mensaje..."; "lng_record_cancel" = "Suelta fuera de aquí para cancelar"; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "¿Qué puede hacer este bot?"; "lng_unblock_button" = "Desbloquear"; +"lng_open_this_link" = "¿Abrir este enlace?"; +"lng_open_link" = "Abrir"; + "lng_bot_start" = "Iniciar"; "lng_bot_choose_group" = "Elegir grupo"; "lng_bot_no_groups" = "No tienes grupos"; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram Desktop fue actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}"; "lng_new_version_minor" = "— Corrección de errores y otras mejoras menores"; -"lng_new_version_text" = "— Incluye los chats silenciados en el conteo de 'no leídos', en Ajustes\n— Vista y búsqueda de los enlaces compartidos, en 'Todos los archivos'\n— Vista previa al enviar enlaces a GIF animados o archivos PDF"; +"lng_new_version_text" = "— Botones para reportar spam en los nuevos chats\n— Otras mejoras y correcciones\n— Notificaciones en OS X 10.8 arregladas"; "lng_menu_insert_unicode" = "Insertar caracteres de control Unicode"; diff --git a/Telegram/SourceFiles/langs/lang_it.strings b/Telegram/SourceFiles/langs/lang_it.strings index dfa4eff43..712aeb38f 100644 --- a/Telegram/SourceFiles/langs/lang_it.strings +++ b/Telegram/SourceFiles/langs/lang_it.strings @@ -403,7 +403,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_create_group_title" = "Nuovo gruppo"; "lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi."; -"lng_failed_add_not_mutual" = "Se una persona lascia un gruppo, solo\nun contatto in comune può reinvitarla\n(chi ti invita deve avere il tuo\ncontatto su Telegram, e viceversa)."; +"lng_failed_add_not_mutual" = "Spiacenti, se una persona lascia un gruppo,\nsolo un contatto in comune può reinvitarla\n(chi ti invita deve avere il tuo\ncontatto su Telegram, e viceversa)."; "lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?"; "lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata."; @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_report_spam" = "Segnala spam"; +"lng_report_spam_hide" = "Nascondi"; +"lng_report_spam_thanks" = "Grazie per la tua segnalazione!"; +"lng_cant_send_to_not_contact" = "Spiacenti, ma al momento puoi scrivere\nsolo a contatti in comune. {more_info}"; +"lng_cant_invite_not_contact" = "Spiacenti, ma al momento puoi aggiungere\nai gruppi solo a contatti in comune. {more_info}"; +"lng_cant_more_info" = "Più info »"; + "lng_send_button" = "Invia"; "lng_message_ph" = "Scrivi un messaggio.."; "lng_record_cancel" = "Rilascia fuori da qui per annullare"; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "Cosa può fare questo bot?"; "lng_unblock_button" = "Sblocca"; +"lng_open_this_link" = "Aprire questo link?"; +"lng_open_link" = "Apri"; + "lng_bot_start" = "Avvia"; "lng_bot_choose_group" = "Scegli gruppo"; "lng_bot_no_groups" = "Non hai gruppi"; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}"; "lng_new_version_minor" = "— Bug fix e altri miglioramenti minori"; -"lng_new_version_text" = "— Includi chat silenziate nel badge nelle Impostazioni\n— Panoramica dei link condivisi e ricerca nei media condivisi\n— Anteprima quando invii una GIF o un file PDF."; +"lng_new_version_text" = "— Pulsante per segnalare lo spam nelle nuove chat\n— Altri fix e miglioramenti\n— Risoluzione problema alle notifiche in OS X 10.8"; "lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode"; diff --git a/Telegram/SourceFiles/langs/lang_ko.strings b/Telegram/SourceFiles/langs/lang_ko.strings index b6c0f4df1..b8bfde487 100644 --- a/Telegram/SourceFiles/langs/lang_ko.strings +++ b/Telegram/SourceFiles/langs/lang_ko.strings @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "스티커"; "lng_in_dlg_sticker_emoji" = "{emoji} (스티커)"; +"lng_report_spam" = "스팸 신고"; +"lng_report_spam_hide" = "숨기기"; +"lng_report_spam_thanks" = "신고해주셔서 감사합니다!"; +"lng_cant_send_to_not_contact" = "죄송하지만, 현재 서로 연락처가 추가된\n회원들끼리만 전송이 가능합니다. {more_info}"; +"lng_cant_invite_not_contact" = "죄송하지만, 현재 서로 연락처가 추가된\n회원들끼리만 추가 가능합니다. {more_info}"; +"lng_cant_more_info" = "자세한 정보 »"; + "lng_send_button" = "보내기"; "lng_message_ph" = "메시지 쓰기"; "lng_record_cancel" = "이 영역 밖에서 마우스 클릭을 해제하시면 취소가 됩니다."; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "봇이 할 수 있는 일은 무엇일까요?"; "lng_unblock_button" = "차단해제"; +"lng_open_this_link" = "이 링크로 이동하시겠나요?"; +"lng_open_link" = "열기"; + "lng_bot_start" = "시작"; "lng_bot_choose_group" = "그룹 선택"; "lng_bot_no_groups" = "그룹이 존재하지 않습니다."; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}"; "lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상"; -"lng_new_version_text" = "— 설정에서 안 읽은 메시지 수에 음소거된 채팅방 포함\n— 공유된 링크 현황과 공유된 미디어 검색 기능\n— GIF 링크 및 PDF 파일 전송시 프리뷰 기능"; +"lng_new_version_text" = "— 스팸 신고 버튼 추가\n— 기타 오류 수정 및 기능 향상\n— OS X 10.8 알림 수정"; "lng_menu_insert_unicode" = "유니코드 문자를 입력하세요."; diff --git a/Telegram/SourceFiles/langs/lang_nl.strings b/Telegram/SourceFiles/langs/lang_nl.strings index 966775c7f..16703c5d9 100644 --- a/Telegram/SourceFiles/langs/lang_nl.strings +++ b/Telegram/SourceFiles/langs/lang_nl.strings @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_report_spam" = "Spam melden"; +"lng_report_spam_hide" = "Verbergen"; +"lng_report_spam_thanks" = "Bedankt voor je melding!"; +"lng_cant_send_to_not_contact" = "Op dit moment kun je alleen berichten\nversturen naar onderlinge contacten. {more_info}"; +"lng_cant_invite_not_contact" = "Op dit moment kun je alleen onderlinge\ncontacten aan groepen toevoegen. {more_info}"; +"lng_cant_more_info" = "Meer informatie »"; + "lng_send_button" = "Stuur"; "lng_message_ph" = "Bericht schrijven"; "lng_record_cancel" = "Annuleren: uit het vak loslaten"; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "Wat kan deze bot? "; "lng_unblock_button" = "Deblokkeer"; +"lng_open_this_link" = "Link openen?"; +"lng_open_link" = "Openen"; + "lng_bot_start" = "Begin"; "lng_bot_choose_group" = "Groep kiezen"; "lng_bot_no_groups" = "Je hebt geen groepen"; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}"; "lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen"; -"lng_new_version_text" = "— Stille chats meetellen in ongelezen teller via instellingen\n— Gedeelde links-overzicht en zoeken in gedeelde media\n— Voorvertoning voor links naar GIF-animaties en PDF-bestanden"; +"lng_new_version_text" = "— 'Spam melden'-optie in nieuwe chats\n— Probleemoplossing en kleine verbeteringen\n— Problemen met OS X 10.8 berichtmeldingen opgelost"; "lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen"; diff --git a/Telegram/SourceFiles/langs/lang_pt_BR.strings b/Telegram/SourceFiles/langs/lang_pt_BR.strings index b41698cc4..84b3bd4c3 100644 --- a/Telegram/SourceFiles/langs/lang_pt_BR.strings +++ b/Telegram/SourceFiles/langs/lang_pt_BR.strings @@ -454,7 +454,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_media_open_with" = "Abrir Com"; "lng_media_download" = "Download"; "lng_media_cancel" = "Cancelar"; -"lng_media_video" = "Vídeos"; +"lng_media_video" = "Vídeo"; "lng_media_audio" = "Mensagem de voz"; "lng_emoji_category0" = "Frequentemente usado"; @@ -485,6 +485,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_in_dlg_sticker" = "Sticker"; "lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_report_spam" = "Reportar Spam"; +"lng_report_spam_hide" = "Ocultar"; +"lng_report_spam_thanks" = "Obrigado por reportar!"; +"lng_cant_send_to_not_contact" = "Você só pode enviar mensagens para\ncontatos mútuos no momento. {more_info}"; +"lng_cant_invite_not_contact" = "Você só pode adicionar contatos\nmútuos ao grupo no momento. {more_info}"; +"lng_cant_more_info" = "Informações »"; + "lng_send_button" = "Enviar"; "lng_message_ph" = "Escrever a mensagem.."; "lng_record_cancel" = "Solte fora desse campo para cancelar"; @@ -495,6 +502,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_bot_description" = "O que esse bot pode fazer?"; "lng_unblock_button" = "Desbloquear"; +"lng_open_this_link" = "Abrir este link?"; +"lng_open_link" = "Abrir"; + "lng_bot_start" = "Iniciar"; "lng_bot_choose_group" = "Escolher Grupo"; "lng_bot_no_groups" = "Você não possui grupos"; @@ -648,7 +658,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}"; "lng_new_version_minor" = "— Resolução de bugs e outras menores melhorias"; -"lng_new_version_text" = "— Incluir chats silenciados no contador de notificações em Configurações\n— Visão geral dos links compartilhados e busca nas mídias compartilhadas\n— Pré-visualização em links com GIF e arquivos em PDF"; +"lng_new_version_text" = "— Botões para reportar spam em novos chats\n— Outras melhorias e resoluções de erros\n— OS X 10.8 problemas com notificações solucionadas"; "lng_menu_insert_unicode" = "Inserir caractere de controle Unicode"; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 58272a3cd..e977faa8e 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -495,19 +495,20 @@ namespace { FileKey _dataNameKey = 0; enum { // Local Storage Keys - lskUserMap = 0x00, - lskDraft = 0x01, // data: PeerId peer - lskDraftPosition = 0x02, // data: PeerId peer - lskImages = 0x03, // data: StorageKey location - lskLocations = 0x04, // no data - lskStickerImages = 0x05, // data: StorageKey location - lskAudios = 0x06, // data: StorageKey location - lskRecentStickersOld = 0x07, // no data - lskBackground = 0x08, // no data - lskUserSettings = 0x09, // no data - lskRecentHashtags = 0x0a, // no data - lskStickers = 0x0b, // no data - lskSavedPeers = 0x0c, // no data + lskUserMap = 0x00, + lskDraft = 0x01, // data: PeerId peer + lskDraftPosition = 0x02, // data: PeerId peer + lskImages = 0x03, // data: StorageKey location + lskLocations = 0x04, // no data + lskStickerImages = 0x05, // data: StorageKey location + lskAudios = 0x06, // data: StorageKey location + lskRecentStickersOld = 0x07, // no data + lskBackground = 0x08, // no data + lskUserSettings = 0x09, // no data + lskRecentHashtags = 0x0a, // no data + lskStickers = 0x0b, // no data + lskSavedPeers = 0x0c, // no data + lskReportSpamStatuses = 0x0d, // no data }; typedef QMap DraftsMap; @@ -522,7 +523,7 @@ namespace { FileLocationPairs _fileLocationPairs; typedef QMap FileLocationAliases; FileLocationAliases _fileLocationAliases; - FileKey _locationsKey = 0; + FileKey _locationsKey = 0, _reportSpamStatusesKey = 0; FileKey _recentStickersKeyOld = 0, _stickersKey = 0; @@ -550,7 +551,7 @@ namespace { }; void _writeMap(WriteMapWhen when = WriteMapSoon); - + void _writeLocations(WriteMapWhen when = WriteMapSoon) { if (when != WriteMapNow) { _manager->writeLocations(when == WriteMapFast); @@ -643,6 +644,63 @@ namespace { } } + void _writeReportSpamStatuses() { + if (!_working()) return; + + if (cReportSpamStatuses().isEmpty()) { + if (_reportSpamStatusesKey) { + clearKey(_reportSpamStatusesKey); + _reportSpamStatusesKey = 0; + _mapChanged = true; + _writeMap(); + } + } else { + if (!_reportSpamStatusesKey) { + _reportSpamStatusesKey = genKey(); + _mapChanged = true; + _writeMap(WriteMapFast); + } + const ReportSpamStatuses &statuses(cReportSpamStatuses()); + + quint32 size = sizeof(qint32); + for (ReportSpamStatuses::const_iterator i = statuses.cbegin(), e = statuses.cend(); i != e; ++i) { + // peer + status + size += sizeof(quint64) + sizeof(qint32); + } + + EncryptedDescriptor data(size); + data.stream << qint32(statuses.size()); + for (ReportSpamStatuses::const_iterator i = statuses.cbegin(), e = statuses.cend(); i != e; ++i) { + data.stream << quint64(i.key()) << qint32(i.value()); + } + + FileWriteDescriptor file(_reportSpamStatusesKey); + file.writeEncrypted(data); + } + } + + void _readReportSpamStatuses() { + FileReadDescriptor statuses; + if (!readEncryptedFile(statuses, _reportSpamStatusesKey)) { + clearKey(_reportSpamStatusesKey); + _reportSpamStatusesKey = 0; + _writeMap(); + return; + } + + ReportSpamStatuses &map(cRefReportSpamStatuses()); + map.clear(); + + qint32 size = 0; + statuses.stream >> size; + for (int32 i = 0; i < size; ++i) { + quint64 peer = 0; + qint32 status = 0; + statuses.stream >> peer >> status; + map.insert(peer, DBIPeerReportSpamStatus(status)); + } + } + mtpDcOptions *_dcOpts = 0; bool _readSetting(quint32 blockId, QDataStream &stream, int version) { switch (blockId) { @@ -1458,7 +1516,7 @@ namespace { DraftsNotReadMap draftsNotReadMap; StorageMap imagesMap, stickerImagesMap, audiosMap; qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0; - quint64 locationsKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0, savedPeersKey = 0; + quint64 locationsKey = 0, reportSpamStatusesKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0, savedPeersKey = 0; while (!map.stream.atEnd()) { quint32 keyType; map.stream >> keyType; @@ -1523,6 +1581,9 @@ namespace { case lskLocations: { map.stream >> locationsKey; } break; + case lskReportSpamStatuses: { + map.stream >> reportSpamStatusesKey; + } break; case lskRecentStickersOld: { map.stream >> recentStickersKeyOld; } break; @@ -1562,6 +1623,7 @@ namespace { _storageAudiosSize = storageAudiosSize; _locationsKey = locationsKey; + _reportSpamStatusesKey = reportSpamStatusesKey; _recentStickersKeyOld = recentStickersKeyOld; _stickersKey = stickersKey; _savedPeersKey = savedPeersKey; @@ -1579,6 +1641,9 @@ namespace { if (_locationsKey) { _readLocations(); } + if (_reportSpamStatusesKey) { + _readReportSpamStatuses(); + } _readUserSettings(); _readMtpData(); @@ -1630,6 +1695,7 @@ namespace { if (!_stickerImagesMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _stickerImagesMap.size() * (sizeof(quint64) * 3 + sizeof(qint32)); if (!_audiosMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _audiosMap.size() * (sizeof(quint64) * 3 + sizeof(qint32)); if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64); + if (_reportSpamStatusesKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64); if (_stickersKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_savedPeersKey) mapSize += sizeof(quint32) + sizeof(quint64); @@ -1670,6 +1736,9 @@ namespace { if (_locationsKey) { mapData.stream << quint32(lskLocations) << quint64(_locationsKey); } + if (_reportSpamStatusesKey) { + mapData.stream << quint32(lskReportSpamStatuses) << quint64(_reportSpamStatusesKey); + } if (_recentStickersKeyOld) { mapData.stream << quint32(lskRecentStickersOld) << quint64(_recentStickersKeyOld); } @@ -1938,7 +2007,7 @@ namespace Local { _draftsNotReadMap.clear(); _stickerImagesMap.clear(); _audiosMap.clear(); - _locationsKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0; + _locationsKey = _reportSpamStatusesKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0; _mapChanged = true; _writeMap(WriteMapNow); @@ -2976,6 +3045,10 @@ namespace Local { } } + void writeReportSpamStatuses() { + _writeReportSpamStatuses(); + } + struct ClearManagerData { QThread *thread; StorageMap images, stickers, audios; @@ -3023,6 +3096,10 @@ namespace Local { _locationsKey = 0; _mapChanged = true; } + if (_reportSpamStatusesKey) { + _reportSpamStatusesKey = 0; + _mapChanged = true; + } if (_recentStickersKeyOld) { _recentStickersKeyOld = 0; _mapChanged = true; diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 11b3f3871..5b20a3f7a 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -147,4 +147,6 @@ namespace Local { void removeSavedPeer(PeerData *peer); void readSavedPeers(); + void writeReportSpamStatuses(); + }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 9364a5808..60c7404b4 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -781,7 +781,12 @@ void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHis updPtsUpdated(d.vpts.v, d.vpts_count.v); int32 offset = d.voffset.v; - if (!MTP::authedId() || offset <= 0) return; + if (!MTP::authedId()) return; + if (offset <= 0) { + cRefReportSpamStatuses().remove(peer->id); + Local::writeReportSpamStatuses(); + return; + } MTP::send(MTPmessages_DeleteHistory(peer->input, d.voffset), rpcDone(&MainWidget::deleteHistoryPart, peer)); } @@ -842,6 +847,8 @@ bool MainWidget::addParticipantFail(UserData *user, const RPCError &error) { text = lang(lng_failed_add_not_mutual); } else if (error.type() == "USER_ALREADY_PARTICIPANT" && user->botInfo) { text = lang(lng_bot_already_in_group); + } else if (error.type() == "PEER_FLOOD") { + text = lng_cant_invite_not_contact(lt_more_info, textcmdLink(qsl("https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts"), lang(lng_cant_more_info))); } App::wnd()->showLayer(new ConfirmBox(text, true)); return false; @@ -912,7 +919,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu } } -bool MainWidget::sendPhotoFailed(uint64 randomId, const RPCError &error) { +bool MainWidget::sendPhotoFail(uint64 randomId, const RPCError &error) { if (mtpIsFlood(error)) return false; if (error.type() == qsl("PHOTO_INVALID_DIMENSIONS")) { @@ -926,6 +933,16 @@ bool MainWidget::sendPhotoFailed(uint64 randomId, const RPCError &error) { _resendImgRandomIds.push_back(randomId); return true; } + return sendMessageFail(error); +} + +bool MainWidget::sendMessageFail(const RPCError &error) { + if (mtpIsFlood(error)) return false; + + if (error.type() == qsl("PEER_FLOOD")) { + App::wnd()->showLayer(new ConfirmBox(lng_cant_send_to_not_contact(lt_more_info, textcmdLink(qsl("https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts"), lang(lng_cant_more_info))), true)); + return true; + } return false; } @@ -1103,8 +1120,8 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl flags |= MTPDmessage::flag_from_id; } MTPVector localEntities = linksToMTP(textParseLinks(sendingText, itemTextParseOptions(hist, App::self()).flags)); - hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities)); - hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, localEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(hist->peer->id), MTPPeer(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities, MTPint())); + hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, localEntities), rpcDone(&MainWidget::sentUpdatesReceived, randomId), rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); } finishForwarding(hist); @@ -1891,7 +1908,7 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia & HistoryItem *item = 0; while (textSplit(sendingText, leftText, MaxMessageSize)) { MTPVector localEntities = linksToMTP(textParseLinks(sendingText, _historyTextOptions.flags)); - item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities), unread ? 1 : 2); + item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPPeer(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint()), unread ? 1 : 2); } if (item) { history.peerMessagesUpdated(item->history()->peer->id); @@ -2067,6 +2084,10 @@ void MainWidget::clearBotStartToken(PeerData *peer) { } } +void MainWidget::contactsReceived() { + history.contactsReceived(); +} + void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) { if (!back && (!peerId || (_stack.size() == 1 && _stack[0]->type() == HistoryStackItem && _stack[0]->peer->id == peerId))) { back = true; @@ -3481,7 +3502,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { case mtpc_updateShortMessage: { const MTPDupdateShortMessage &d(updates.c_updateShortMessage()); - if (!App::userLoaded(d.vuser_id.v) || (d.has_fwd_from_id() && !App::userLoaded(d.vfwd_from_id.v))) { + if (!App::userLoaded(d.vuser_id.v) || (d.has_fwd_from_id() && !App::peerLoaded(peerFromMTP(d.vfwd_from_id)))) { MTP_LOG(0, ("getDifference { good - getting user for updateShortMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); return getDifference(); } @@ -3490,7 +3511,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { return; } bool out = (d.vflags.v & MTPDmessage_flag_out); - HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities)); + HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint())); if (item) { history.peerMessagesUpdated(item->history()->peer->id); } @@ -3501,7 +3522,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { case mtpc_updateShortChatMessage: { const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage()); bool noFrom = !App::userLoaded(d.vfrom_id.v); - if (!App::chatLoaded(d.vchat_id.v) || noFrom || (d.has_fwd_from_id() && !App::userLoaded(d.vfwd_from_id.v))) { + if (!App::chatLoaded(d.vchat_id.v) || noFrom || (d.has_fwd_from_id() && !App::peerLoaded(peerFromMTP(d.vfwd_from_id)))) { MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); if (noFrom) App::api()->requestFullPeer(App::chatLoaded(d.vchat_id.v)); return getDifference(); @@ -3510,7 +3531,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { _byPtsUpdates.insert(ptsKey(SkippedUpdates), updates); return; } - HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities)); + HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint())); if (item) { history.peerMessagesUpdated(item->history()->peer->id); } @@ -3526,7 +3547,6 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { App::histSentDataByItem(randomId, peerId, text); feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date - if (peerId) { HistoryItem *item = App::histItemById(peerToChannel(peerId), d.vid.v); if (!text.isEmpty()) { @@ -3534,7 +3554,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) { if (item && ((hasLinks && !item->hasTextLinks()) || (!hasLinks && item->textHasLinks()))) { bool was = item->hasTextLinks(); item->setText(text, d.has_entities() ? linksFromMTP(d.ventities.c_vector().v) : LinksInText()); - item->initDimensions(0); + item->initDimensions(); itemResized(item); if (!was && item->hasTextLinks()) { item->history()->addToOverview(item, OverviewLinks); @@ -3661,6 +3681,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateWebPage: { const MTPDupdateWebPage &d(update.c_updateWebPage()); + if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { + _byPtsUpdate.insert(ptsKey(SkippedUpdate), update); + return; + } App::feedWebPage(d.vwebpage); history.updatePreview(); webPagesUpdate(); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 96fb89df9..50ce9f108 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -300,7 +300,8 @@ public: void checkPeerHistory(PeerData *peer); void checkedHistory(PeerData *peer, const MTPmessages_Messages &result); - bool sendPhotoFailed(uint64 randomId, const RPCError &e); + bool sendPhotoFail(uint64 randomId, const RPCError &e); + bool sendMessageFail(const RPCError &error); void forwardSelectedItems(); void deleteSelectedItems(); @@ -377,6 +378,8 @@ public: void choosePeer(PeerId peerId, MsgId showAtMsgId); // does offerPeer or showPeerHistory void clearBotStartToken(PeerData *peer); + void contactsReceived(); + ~MainWidget(); signals: diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 300942606..9b2cf778a 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -206,11 +206,15 @@ void MediaView::updateDocSize() { readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10); totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10); mb = qsl("MB"); - } else { + } else if (total >= 1024) { qint64 readyKb = (ready / 1024), totalKb = (total / 1024); readyStr = QString::number(readyKb); totalStr = QString::number(totalKb); mb = qsl("KB"); + } else { + readyStr = QString::number(ready); + totalStr = QString::number(total); + mb = qsl("B"); } _docSize = lng_media_save_progress(lt_ready, readyStr, lt_total, totalStr, lt_mb, mb); } else { diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp index cb0cabfbb..a70151710 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp +++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp @@ -1216,12 +1216,13 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP to.add("\n").addSpaces(lev); } switch (stage) { - case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } break; @@ -1360,6 +1361,21 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_channelParticipants: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ channelParticipants"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" self_participant: "); ++stages.back(); if (flag & MTPDchannelParticipants::flag_self_participant) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + case mtpc_chatPhotoEmpty: to.add("{ chatPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; @@ -1403,7 +1419,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 2: to.add(" from_id: "); ++stages.back(); if (flag & MTPDmessage::flag_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break; case 3: to.add(" to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 4: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_from_id) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 5: to.add(" fwd_date: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 6: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; case 7: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; @@ -1411,6 +1427,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP case 9: to.add(" media: "); ++stages.back(); if (flag & MTPDmessage::flag_media) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break; case 10: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break; case 11: to.add(" entities: "); ++stages.back(); if (flag & MTPDmessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break; + case 12: to.add(" views: "); ++stages.back(); if (flag & MTPDmessage::flag_views) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } break; @@ -2912,7 +2929,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP case 4: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 5: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 6: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 7: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 7: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_from_id) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 8: to.add(" fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 9: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; case 10: to.add(" entities: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break; @@ -2936,7 +2953,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP case 5: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 6: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 7: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 8: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 8: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_from_id) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 9: to.add(" fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; case 10: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; case 11: to.add(" entities: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break; @@ -4668,6 +4685,36 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_channelParticipant: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ channelParticipant"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + + case mtpc_messages_channelParticipants: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ messages_channelParticipants"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" participants: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + case mtpc_req_pq: if (stage) { to.add(",\n").addSpaces(lev); @@ -5154,6 +5201,20 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_messages_incrementMessagesViews: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ messages_incrementMessagesViews"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + case mtpc_messages_editChatAbout: if (stage) { to.add(",\n").addSpaces(lev); @@ -5782,6 +5843,20 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_messages_getChannelMessages: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ messages_getChannelMessages"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + case mtpc_messages_getDialogs: if (stage) { to.add(",\n").addSpaces(lev); @@ -5937,9 +6012,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP to.add("\n").addSpaces(lev); } switch (stage) { - case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 0: to.add(" from_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 1: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break; case 2: to.add(" random_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" to_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } break; @@ -6311,6 +6387,21 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_messages_getChannelParticipants: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ messages_getChannelParticipants"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } + break; + case mtpc_updates_getState: to.add("{ updates_getState }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h index 348fd3c52..a583fc749 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.h +++ b/Telegram/SourceFiles/mtproto/mtpScheme.h @@ -133,7 +133,7 @@ enum { mtpc_userStatusLastWeek = 0x7bf09fc, mtpc_userStatusLastMonth = 0x77ebc742, mtpc_chatEmpty = 0x9ba2d800, - mtpc_chat = 0xc7c02794, + mtpc_chat = 0x7312bc48, mtpc_chatForbidden = 0x7328bdb, mtpc_channel = 0x1bcc63f2, mtpc_channelForbidden = 0x2d85832c, @@ -142,10 +142,11 @@ enum { mtpc_chatParticipant = 0xc8d7493e, mtpc_chatParticipantsForbidden = 0xfc900c2b, mtpc_chatParticipants = 0x7841b415, + mtpc_channelParticipants = 0xb561ad0c, mtpc_chatPhotoEmpty = 0x37c1011c, mtpc_chatPhoto = 0x6153276a, mtpc_messageEmpty = 0x83e5de54, - mtpc_message = 0xab406723, + mtpc_message = 0x5ba66c13, mtpc_messageService = 0xc06b9607, mtpc_messageMediaEmpty = 0x3ded6320, mtpc_messageMediaPhoto = 0x3d8ce53d, @@ -263,8 +264,8 @@ enum { mtpc_updates_difference = 0xf49ca0, mtpc_updates_differenceSlice = 0xa8fb1981, mtpc_updatesTooLong = 0xe317af7e, - mtpc_updateShortMessage = 0x3f32d858, - mtpc_updateShortChatMessage = 0xf9409b3d, + mtpc_updateShortMessage = 0xf7d91a46, + mtpc_updateShortChatMessage = 0xcac7fdd2, mtpc_updateShort = 0x78d4dec1, mtpc_updatesCombined = 0x725b04c3, mtpc_updates = 0x74ae4240, @@ -408,6 +409,8 @@ enum { mtpc_channelMessagesFilter = 0xcd77d957, mtpc_channelMessagesFilterCollapsed = 0xfa01232e, mtpc_contacts_resolvedPeer = 0x7f077ad9, + mtpc_channelParticipant = 0x506116ea, + mtpc_messages_channelParticipants = 0xd6891de1, mtpc_invokeAfterMsg = 0xcb9f372d, mtpc_invokeAfterMsgs = 0x3dc4b4f0, mtpc_initConnection = 0x69796de9, @@ -478,7 +481,7 @@ enum { mtpc_messages_setTyping = 0xa3825e50, mtpc_messages_sendMessage = 0xfa88427a, mtpc_messages_sendMedia = 0xc8f16791, - mtpc_messages_forwardMessages = 0x55e1728d, + mtpc_messages_forwardMessages = 0xf9adea76, mtpc_messages_reportSpam = 0xcf1592db, mtpc_messages_getChats = 0x27ae65b, mtpc_messages_getFullChat = 0x36a4dfe, @@ -515,7 +518,10 @@ enum { mtpc_messages_readChannelHistory = 0x36a1210e, mtpc_messages_createChannel = 0xe830f8cb, mtpc_messages_deleteChannelMessages = 0x9995a84f, + mtpc_messages_getChannelMessages = 0x5f46b265, + mtpc_messages_incrementMessagesViews = 0x91ffd479, mtpc_messages_editChatAbout = 0x8a969b93, + mtpc_messages_getChannelParticipants = 0x4a771976, mtpc_messages_checkChannelUsername = 0xe6d2d8f4, mtpc_messages_updateChannelUsername = 0xce2e9587, mtpc_updates_getState = 0xedd4882a, @@ -707,6 +713,7 @@ class MTPDchatParticipant; class MTPchatParticipants; class MTPDchatParticipantsForbidden; class MTPDchatParticipants; +class MTPDchannelParticipants; class MTPchatPhoto; class MTPDchatPhoto; @@ -1117,6 +1124,12 @@ class MTPDchannelMessagesFilter; class MTPcontacts_resolvedPeer; class MTPDcontacts_resolvedPeer; +class MTPchannelParticipant; +class MTPDchannelParticipant; + +class MTPmessages_channelParticipants; +class MTPDmessages_channelParticipants; + // Boxed types definitions typedef MTPBoxed MTPResPQ; @@ -1267,6 +1280,8 @@ typedef MTPBoxed MTPMessageGroup; typedef MTPBoxed MTPupdates_ChannelDifference; typedef MTPBoxed MTPChannelMessagesFilter; typedef MTPBoxed MTPcontacts_ResolvedPeer; +typedef MTPBoxed MTPChannelParticipant; +typedef MTPBoxed MTPmessages_ChannelParticipants; // Type classes definitions @@ -3194,7 +3209,7 @@ private: explicit MTPchat(MTPDchannelForbidden *_data); friend MTPchat MTP_chatEmpty(MTPint _id); - friend MTPchat MTP_chat(MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version); + friend MTPchat MTP_chat(MTPint _flags, MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version); friend MTPchat MTP_chatForbidden(MTPint _id, const MTPstring &_title); friend MTPchat MTP_channel(MTPint _flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_username, const MTPChatPhoto &_photo, MTPint _date, MTPint _version); friend MTPchat MTP_channelForbidden(MTPint _id, const MTPlong &_access_hash, const MTPstring &_title); @@ -3317,6 +3332,18 @@ public: return *(const MTPDchatParticipants*)data; } + MTPDchannelParticipants &_channelParticipants() { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_channelParticipants) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipants); + split(); + return *(MTPDchannelParticipants*)data; + } + const MTPDchannelParticipants &c_channelParticipants() const { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_channelParticipants) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipants); + return *(const MTPDchannelParticipants*)data; + } + uint32 innerLength() const; mtpTypeId type() const; void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons); @@ -3328,9 +3355,11 @@ private: explicit MTPchatParticipants(mtpTypeId type); explicit MTPchatParticipants(MTPDchatParticipantsForbidden *_data); explicit MTPchatParticipants(MTPDchatParticipants *_data); + explicit MTPchatParticipants(MTPDchannelParticipants *_data); friend MTPchatParticipants MTP_chatParticipantsForbidden(MTPint _flags, MTPint _chat_id, const MTPChatParticipant &_self_participant); friend MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, MTPint _admin_id, const MTPVector &_participants, MTPint _version); + friend MTPchatParticipants MTP_channelParticipants(MTPint _flags, MTPint _channel_id, const MTPChatParticipant &_self_participant); mtpTypeId _type; }; @@ -3432,7 +3461,7 @@ private: explicit MTPmessage(MTPDmessageService *_data); friend MTPmessage MTP_messageEmpty(MTPint _id); - friend MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities); + friend MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities, MTPint _views); friend MTPmessage MTP_messageService(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPMessageAction &_action); mtpTypeId _type; @@ -5596,8 +5625,8 @@ private: explicit MTPupdates(MTPDupdateShortSentMessage *_data); friend MTPupdates MTP_updatesTooLong(); - friend MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities); - friend MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities); + friend MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities); + friend MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities); friend MTPupdates MTP_updateShort(const MTPUpdate &_update, MTPint _date); friend MTPupdates MTP_updatesCombined(const MTPVector &_updates, const MTPVector &_users, const MTPVector &_chats, MTPint _date, MTPint _seq_start, MTPint _seq); friend MTPupdates MTP_updates(const MTPVector &_updates, const MTPVector &_users, const MTPVector &_chats, MTPint _date, MTPint _seq); @@ -8328,6 +8357,68 @@ private: }; typedef MTPBoxed MTPcontacts_ResolvedPeer; +class MTPchannelParticipant : private mtpDataOwner { +public: + MTPchannelParticipant(); + MTPchannelParticipant(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channelParticipant) : mtpDataOwner(0) { + read(from, end, cons); + } + + MTPDchannelParticipant &_channelParticipant() { + if (!data) throw mtpErrorUninitialized(); + split(); + return *(MTPDchannelParticipant*)data; + } + const MTPDchannelParticipant &c_channelParticipant() const { + if (!data) throw mtpErrorUninitialized(); + return *(const MTPDchannelParticipant*)data; + } + + uint32 innerLength() const; + mtpTypeId type() const; + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channelParticipant); + void write(mtpBuffer &to) const; + + typedef void ResponseType; + +private: + explicit MTPchannelParticipant(MTPDchannelParticipant *_data); + + friend MTPchannelParticipant MTP_channelParticipant(MTPint _user_id, MTPint _inviter_id, MTPint _date); +}; +typedef MTPBoxed MTPChannelParticipant; + +class MTPmessages_channelParticipants : private mtpDataOwner { +public: + MTPmessages_channelParticipants(); + MTPmessages_channelParticipants(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_channelParticipants) : mtpDataOwner(0) { + read(from, end, cons); + } + + MTPDmessages_channelParticipants &_messages_channelParticipants() { + if (!data) throw mtpErrorUninitialized(); + split(); + return *(MTPDmessages_channelParticipants*)data; + } + const MTPDmessages_channelParticipants &c_messages_channelParticipants() const { + if (!data) throw mtpErrorUninitialized(); + return *(const MTPDmessages_channelParticipants*)data; + } + + uint32 innerLength() const; + mtpTypeId type() const; + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_channelParticipants); + void write(mtpBuffer &to) const; + + typedef void ResponseType; + +private: + explicit MTPmessages_channelParticipants(MTPDmessages_channelParticipants *_data); + + friend MTPmessages_channelParticipants MTP_messages_channelParticipants(MTPint _count, const MTPVector &_participants, const MTPVector &_users); +}; +typedef MTPBoxed MTPmessages_ChannelParticipants; + // Type constructors with data class MTPDresPQ : public mtpDataImpl { @@ -9185,9 +9276,10 @@ class MTPDchat : public mtpDataImpl { public: MTPDchat() { } - MTPDchat(MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version) : vid(_id), vtitle(_title), vphoto(_photo), vparticipants_count(_participants_count), vdate(_date), vversion(_version) { + MTPDchat(MTPint _flags, MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version) : vflags(_flags), vid(_id), vtitle(_title), vphoto(_photo), vparticipants_count(_participants_count), vdate(_date), vversion(_version) { } + MTPint vflags; MTPint vid; MTPstring vtitle; MTPChatPhoto vphoto; @@ -9318,6 +9410,24 @@ public: MTPint vversion; }; +class MTPDchannelParticipants : public mtpDataImpl { +public: + MTPDchannelParticipants() { + } + MTPDchannelParticipants(MTPint _flags, MTPint _channel_id, const MTPChatParticipant &_self_participant) : vflags(_flags), vchannel_id(_channel_id), vself_participant(_self_participant) { + } + + MTPint vflags; + MTPint vchannel_id; + MTPChatParticipant vself_participant; + + enum { + flag_self_participant = (1 << 0), + }; + + bool has_self_participant() const { return vflags.v & flag_self_participant; } +}; + class MTPDchatPhoto : public mtpDataImpl { public: MTPDchatPhoto() { @@ -9343,14 +9453,14 @@ class MTPDmessage : public mtpDataImpl { public: MTPDmessage() { } - MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities) : vflags(_flags), vid(_id), vfrom_id(_from_id), vto_id(_to_id), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), vdate(_date), vmessage(_message), vmedia(_media), vreply_markup(_reply_markup), ventities(_entities) { + MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities, MTPint _views) : vflags(_flags), vid(_id), vfrom_id(_from_id), vto_id(_to_id), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), vdate(_date), vmessage(_message), vmedia(_media), vreply_markup(_reply_markup), ventities(_entities), vviews(_views) { } MTPint vflags; MTPint vid; MTPint vfrom_id; MTPPeer vto_id; - MTPint vfwd_from_id; + MTPPeer vfwd_from_id; MTPint vfwd_date; MTPint vreply_to_msg_id; MTPint vdate; @@ -9358,6 +9468,7 @@ public: MTPMessageMedia vmedia; MTPReplyMarkup vreply_markup; MTPVector ventities; + MTPint vviews; enum { flag_from_id = (1 << 8), @@ -9367,6 +9478,7 @@ public: flag_media = (1 << 9), flag_reply_markup = (1 << 6), flag_entities = (1 << 7), + flag_views = (1 << 10), }; bool has_from_id() const { return vflags.v & flag_from_id; } @@ -9376,6 +9488,7 @@ public: bool has_media() const { return vflags.v & flag_media; } bool has_reply_markup() const { return vflags.v & flag_reply_markup; } bool has_entities() const { return vflags.v & flag_entities; } + bool has_views() const { return vflags.v & flag_views; } }; class MTPDmessageService : public mtpDataImpl { @@ -10501,7 +10614,7 @@ class MTPDupdateShortMessage : public mtpDataImpl { public: MTPDupdateShortMessage() { } - MTPDupdateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) : vflags(_flags), vid(_id), vuser_id(_user_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { + MTPDupdateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) : vflags(_flags), vid(_id), vuser_id(_user_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { } MTPint vflags; @@ -10511,7 +10624,7 @@ public: MTPint vpts; MTPint vpts_count; MTPint vdate; - MTPint vfwd_from_id; + MTPPeer vfwd_from_id; MTPint vfwd_date; MTPint vreply_to_msg_id; MTPVector ventities; @@ -10533,7 +10646,7 @@ class MTPDupdateShortChatMessage : public mtpDataImpl &_entities) : vflags(_flags), vid(_id), vfrom_id(_from_id), vchat_id(_chat_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { + MTPDupdateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) : vflags(_flags), vid(_id), vfrom_id(_from_id), vchat_id(_chat_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { } MTPint vflags; @@ -10544,7 +10657,7 @@ public: MTPint vpts; MTPint vpts_count; MTPint vdate; - MTPint vfwd_from_id; + MTPPeer vfwd_from_id; MTPint vfwd_date; MTPint vreply_to_msg_id; MTPVector ventities; @@ -11885,6 +11998,30 @@ public: MTPVector vusers; }; +class MTPDchannelParticipant : public mtpDataImpl { +public: + MTPDchannelParticipant() { + } + MTPDchannelParticipant(MTPint _user_id, MTPint _inviter_id, MTPint _date) : vuser_id(_user_id), vinviter_id(_inviter_id), vdate(_date) { + } + + MTPint vuser_id; + MTPint vinviter_id; + MTPint vdate; +}; + +class MTPDmessages_channelParticipants : public mtpDataImpl { +public: + MTPDmessages_channelParticipants() { + } + MTPDmessages_channelParticipants(MTPint _count, const MTPVector &_participants, const MTPVector &_users) : vcount(_count), vparticipants(_participants), vusers(_users) { + } + + MTPint vcount; + MTPVector vparticipants; + MTPVector vusers; +}; + // RPC methods class MTPreq_pq { // RPC method 'req_pq' @@ -15160,33 +15297,36 @@ public: class MTPmessages_forwardMessages { // RPC method 'messages.forwardMessages' public: - MTPInputPeer vpeer; + MTPInputPeer vfrom_peer; MTPVector vid; MTPVector vrandom_id; + MTPInputPeer vto_peer; MTPmessages_forwardMessages() { } MTPmessages_forwardMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_forwardMessages) { read(from, end, cons); } - MTPmessages_forwardMessages(const MTPInputPeer &_peer, const MTPVector &_id, const MTPVector &_random_id) : vpeer(_peer), vid(_id), vrandom_id(_random_id) { + MTPmessages_forwardMessages(const MTPInputPeer &_from_peer, const MTPVector &_id, const MTPVector &_random_id, const MTPInputPeer &_to_peer) : vfrom_peer(_from_peer), vid(_id), vrandom_id(_random_id), vto_peer(_to_peer) { } uint32 innerLength() const { - return vpeer.innerLength() + vid.innerLength() + vrandom_id.innerLength(); + return vfrom_peer.innerLength() + vid.innerLength() + vrandom_id.innerLength() + vto_peer.innerLength(); } mtpTypeId type() const { return mtpc_messages_forwardMessages; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_forwardMessages) { - vpeer.read(from, end); + vfrom_peer.read(from, end); vid.read(from, end); vrandom_id.read(from, end); + vto_peer.read(from, end); } void write(mtpBuffer &to) const { - vpeer.write(to); + vfrom_peer.write(to); vid.write(to); vrandom_id.write(to); + vto_peer.write(to); } typedef MTPUpdates ResponseType; @@ -15199,7 +15339,7 @@ public: } MTPmessages_ForwardMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_ForwardMessages(const MTPInputPeer &_peer, const MTPVector &_id, const MTPVector &_random_id) : MTPBoxed(MTPmessages_forwardMessages(_peer, _id, _random_id)) { + MTPmessages_ForwardMessages(const MTPInputPeer &_from_peer, const MTPVector &_id, const MTPVector &_random_id, const MTPInputPeer &_to_peer) : MTPBoxed(MTPmessages_forwardMessages(_from_peer, _id, _random_id, _to_peer)) { } }; @@ -16727,6 +16867,90 @@ public: } }; +class MTPmessages_getChannelMessages { // RPC method 'messages.getChannelMessages' +public: + MTPInputPeer vpeer; + MTPVector vid; + + MTPmessages_getChannelMessages() { + } + MTPmessages_getChannelMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getChannelMessages) { + read(from, end, cons); + } + MTPmessages_getChannelMessages(const MTPInputPeer &_peer, const MTPVector &_id) : vpeer(_peer), vid(_id) { + } + + uint32 innerLength() const { + return vpeer.innerLength() + vid.innerLength(); + } + mtpTypeId type() const { + return mtpc_messages_getChannelMessages; + } + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getChannelMessages) { + vpeer.read(from, end); + vid.read(from, end); + } + void write(mtpBuffer &to) const { + vpeer.write(to); + vid.write(to); + } + + typedef MTPmessages_Messages ResponseType; +}; +class MTPmessages_GetChannelMessages : public MTPBoxed { +public: + MTPmessages_GetChannelMessages() { + } + MTPmessages_GetChannelMessages(const MTPmessages_getChannelMessages &v) : MTPBoxed(v) { + } + MTPmessages_GetChannelMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { + } + MTPmessages_GetChannelMessages(const MTPInputPeer &_peer, const MTPVector &_id) : MTPBoxed(MTPmessages_getChannelMessages(_peer, _id)) { + } +}; + +class MTPmessages_incrementMessagesViews { // RPC method 'messages.incrementMessagesViews' +public: + MTPInputPeer vpeer; + MTPVector vid; + + MTPmessages_incrementMessagesViews() { + } + MTPmessages_incrementMessagesViews(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_incrementMessagesViews) { + read(from, end, cons); + } + MTPmessages_incrementMessagesViews(const MTPInputPeer &_peer, const MTPVector &_id) : vpeer(_peer), vid(_id) { + } + + uint32 innerLength() const { + return vpeer.innerLength() + vid.innerLength(); + } + mtpTypeId type() const { + return mtpc_messages_incrementMessagesViews; + } + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_incrementMessagesViews) { + vpeer.read(from, end); + vid.read(from, end); + } + void write(mtpBuffer &to) const { + vpeer.write(to); + vid.write(to); + } + + typedef MTPBool ResponseType; +}; +class MTPmessages_IncrementMessagesViews : public MTPBoxed { +public: + MTPmessages_IncrementMessagesViews() { + } + MTPmessages_IncrementMessagesViews(const MTPmessages_incrementMessagesViews &v) : MTPBoxed(v) { + } + MTPmessages_IncrementMessagesViews(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { + } + MTPmessages_IncrementMessagesViews(const MTPInputPeer &_peer, const MTPVector &_id) : MTPBoxed(MTPmessages_incrementMessagesViews(_peer, _id)) { + } +}; + class MTPmessages_editChatAbout { // RPC method 'messages.editChatAbout' public: MTPInputChat vchat_id; @@ -16769,6 +16993,51 @@ public: } }; +class MTPmessages_getChannelParticipants { // RPC method 'messages.getChannelParticipants' +public: + MTPInputChat vchat_id; + MTPint voffset; + MTPint vlimit; + + MTPmessages_getChannelParticipants() { + } + MTPmessages_getChannelParticipants(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getChannelParticipants) { + read(from, end, cons); + } + MTPmessages_getChannelParticipants(const MTPInputChat &_chat_id, MTPint _offset, MTPint _limit) : vchat_id(_chat_id), voffset(_offset), vlimit(_limit) { + } + + uint32 innerLength() const { + return vchat_id.innerLength() + voffset.innerLength() + vlimit.innerLength(); + } + mtpTypeId type() const { + return mtpc_messages_getChannelParticipants; + } + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getChannelParticipants) { + vchat_id.read(from, end); + voffset.read(from, end); + vlimit.read(from, end); + } + void write(mtpBuffer &to) const { + vchat_id.write(to); + voffset.write(to); + vlimit.write(to); + } + + typedef MTPmessages_ChannelParticipants ResponseType; +}; +class MTPmessages_GetChannelParticipants : public MTPBoxed { +public: + MTPmessages_GetChannelParticipants() { + } + MTPmessages_GetChannelParticipants(const MTPmessages_getChannelParticipants &v) : MTPBoxed(v) { + } + MTPmessages_GetChannelParticipants(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { + } + MTPmessages_GetChannelParticipants(const MTPInputChat &_chat_id, MTPint _offset, MTPint _limit) : MTPBoxed(MTPmessages_getChannelParticipants(_chat_id, _offset, _limit)) { + } +}; + class MTPmessages_checkChannelUsername { // RPC method 'messages.checkChannelUsername' public: MTPInputChat vchat_id; @@ -19981,7 +20250,7 @@ inline uint32 MTPchat::innerLength() const { } case mtpc_chat: { const MTPDchat &v(c_chat()); - return v.vid.innerLength() + v.vtitle.innerLength() + v.vphoto.innerLength() + v.vparticipants_count.innerLength() + v.vdate.innerLength() + v.vversion.innerLength(); + return v.vflags.innerLength() + v.vid.innerLength() + v.vtitle.innerLength() + v.vphoto.innerLength() + v.vparticipants_count.innerLength() + v.vdate.innerLength() + v.vversion.innerLength(); } case mtpc_chatForbidden: { const MTPDchatForbidden &v(c_chatForbidden()); @@ -20013,6 +20282,7 @@ inline void MTPchat::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId case mtpc_chat: _type = cons; { if (!data) setData(new MTPDchat()); MTPDchat &v(_chat()); + v.vflags.read(from, end); v.vid.read(from, end); v.vtitle.read(from, end); v.vphoto.read(from, end); @@ -20056,6 +20326,7 @@ inline void MTPchat::write(mtpBuffer &to) const { } break; case mtpc_chat: { const MTPDchat &v(c_chat()); + v.vflags.write(to); v.vid.write(to); v.vtitle.write(to); v.vphoto.write(to); @@ -20110,8 +20381,8 @@ inline MTPchat::MTPchat(MTPDchannelForbidden *_data) : mtpDataOwner(_data), _typ inline MTPchat MTP_chatEmpty(MTPint _id) { return MTPchat(new MTPDchatEmpty(_id)); } -inline MTPchat MTP_chat(MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version) { - return MTPchat(new MTPDchat(_id, _title, _photo, _participants_count, _date, _version)); +inline MTPchat MTP_chat(MTPint _flags, MTPint _id, const MTPstring &_title, const MTPChatPhoto &_photo, MTPint _participants_count, MTPint _date, MTPint _version) { + return MTPchat(new MTPDchat(_flags, _id, _title, _photo, _participants_count, _date, _version)); } inline MTPchat MTP_chatForbidden(MTPint _id, const MTPstring &_title) { return MTPchat(new MTPDchatForbidden(_id, _title)); @@ -20253,6 +20524,10 @@ inline uint32 MTPchatParticipants::innerLength() const { const MTPDchatParticipants &v(c_chatParticipants()); return v.vchat_id.innerLength() + v.vadmin_id.innerLength() + v.vparticipants.innerLength() + v.vversion.innerLength(); } + case mtpc_channelParticipants: { + const MTPDchannelParticipants &v(c_channelParticipants()); + return v.vflags.innerLength() + v.vchannel_id.innerLength() + (v.has_self_participant() ? v.vself_participant.innerLength() : 0); + } } return 0; } @@ -20278,6 +20553,13 @@ inline void MTPchatParticipants::read(const mtpPrime *&from, const mtpPrime *end v.vparticipants.read(from, end); v.vversion.read(from, end); } break; + case mtpc_channelParticipants: _type = cons; { + if (!data) setData(new MTPDchannelParticipants()); + MTPDchannelParticipants &v(_channelParticipants()); + v.vflags.read(from, end); + v.vchannel_id.read(from, end); + if (v.has_self_participant()) { v.vself_participant.read(from, end); } else { v.vself_participant = MTPChatParticipant(); } + } break; default: throw mtpErrorUnexpected(cons, "MTPchatParticipants"); } } @@ -20296,12 +20578,19 @@ inline void MTPchatParticipants::write(mtpBuffer &to) const { v.vparticipants.write(to); v.vversion.write(to); } break; + case mtpc_channelParticipants: { + const MTPDchannelParticipants &v(c_channelParticipants()); + v.vflags.write(to); + v.vchannel_id.write(to); + if (v.has_self_participant()) v.vself_participant.write(to); + } break; } } inline MTPchatParticipants::MTPchatParticipants(mtpTypeId type) : mtpDataOwner(0), _type(type) { switch (type) { case mtpc_chatParticipantsForbidden: setData(new MTPDchatParticipantsForbidden()); break; case mtpc_chatParticipants: setData(new MTPDchatParticipants()); break; + case mtpc_channelParticipants: setData(new MTPDchannelParticipants()); break; default: throw mtpErrorBadTypeId(type, "MTPchatParticipants"); } } @@ -20309,12 +20598,17 @@ inline MTPchatParticipants::MTPchatParticipants(MTPDchatParticipantsForbidden *_ } inline MTPchatParticipants::MTPchatParticipants(MTPDchatParticipants *_data) : mtpDataOwner(_data), _type(mtpc_chatParticipants) { } +inline MTPchatParticipants::MTPchatParticipants(MTPDchannelParticipants *_data) : mtpDataOwner(_data), _type(mtpc_channelParticipants) { +} inline MTPchatParticipants MTP_chatParticipantsForbidden(MTPint _flags, MTPint _chat_id, const MTPChatParticipant &_self_participant) { return MTPchatParticipants(new MTPDchatParticipantsForbidden(_flags, _chat_id, _self_participant)); } inline MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, MTPint _admin_id, const MTPVector &_participants, MTPint _version) { return MTPchatParticipants(new MTPDchatParticipants(_chat_id, _admin_id, _participants, _version)); } +inline MTPchatParticipants MTP_channelParticipants(MTPint _flags, MTPint _channel_id, const MTPChatParticipant &_self_participant) { + return MTPchatParticipants(new MTPDchannelParticipants(_flags, _channel_id, _self_participant)); +} inline uint32 MTPchatPhoto::innerLength() const { switch (_type) { @@ -20375,7 +20669,7 @@ inline uint32 MTPmessage::innerLength() const { } case mtpc_message: { const MTPDmessage &v(c_message()); - return v.vflags.innerLength() + v.vid.innerLength() + (v.has_from_id() ? v.vfrom_id.innerLength() : 0) + v.vto_id.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vdate.innerLength() + v.vmessage.innerLength() + (v.has_media() ? v.vmedia.innerLength() : 0) + (v.has_reply_markup() ? v.vreply_markup.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0); + return v.vflags.innerLength() + v.vid.innerLength() + (v.has_from_id() ? v.vfrom_id.innerLength() : 0) + v.vto_id.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vdate.innerLength() + v.vmessage.innerLength() + (v.has_media() ? v.vmedia.innerLength() : 0) + (v.has_reply_markup() ? v.vreply_markup.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0) + (v.has_views() ? v.vviews.innerLength() : 0); } case mtpc_messageService: { const MTPDmessageService &v(c_messageService()); @@ -20403,7 +20697,7 @@ inline void MTPmessage::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vid.read(from, end); if (v.has_from_id()) { v.vfrom_id.read(from, end); } else { v.vfrom_id = MTPint(); } v.vto_id.read(from, end); - if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); } + if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPPeer(); } if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); } if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); } v.vdate.read(from, end); @@ -20411,6 +20705,7 @@ inline void MTPmessage::read(const mtpPrime *&from, const mtpPrime *end, mtpType if (v.has_media()) { v.vmedia.read(from, end); } else { v.vmedia = MTPMessageMedia(); } if (v.has_reply_markup()) { v.vreply_markup.read(from, end); } else { v.vreply_markup = MTPReplyMarkup(); } if (v.has_entities()) { v.ventities.read(from, end); } else { v.ventities = MTPVector(); } + if (v.has_views()) { v.vviews.read(from, end); } else { v.vviews = MTPint(); } } break; case mtpc_messageService: _type = cons; { if (!data) setData(new MTPDmessageService()); @@ -20445,6 +20740,7 @@ inline void MTPmessage::write(mtpBuffer &to) const { if (v.has_media()) v.vmedia.write(to); if (v.has_reply_markup()) v.vreply_markup.write(to); if (v.has_entities()) v.ventities.write(to); + if (v.has_views()) v.vviews.write(to); } break; case mtpc_messageService: { const MTPDmessageService &v(c_messageService()); @@ -20474,8 +20770,8 @@ inline MTPmessage::MTPmessage(MTPDmessageService *_data) : mtpDataOwner(_data), inline MTPmessage MTP_messageEmpty(MTPint _id) { return MTPmessage(new MTPDmessageEmpty(_id)); } -inline MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities) { - return MTPmessage(new MTPDmessage(_flags, _id, _from_id, _to_id, _fwd_from_id, _fwd_date, _reply_to_msg_id, _date, _message, _media, _reply_markup, _entities)); +inline MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media, const MTPReplyMarkup &_reply_markup, const MTPVector &_entities, MTPint _views) { + return MTPmessage(new MTPDmessage(_flags, _id, _from_id, _to_id, _fwd_from_id, _fwd_date, _reply_to_msg_id, _date, _message, _media, _reply_markup, _entities, _views)); } inline MTPmessage MTP_messageService(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPMessageAction &_action) { return MTPmessage(new MTPDmessageService(_flags, _id, _from_id, _to_id, _date, _action)); @@ -23362,7 +23658,7 @@ inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vpts.read(from, end); v.vpts_count.read(from, end); v.vdate.read(from, end); - if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); } + if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPPeer(); } if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); } if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); } if (v.has_entities()) { v.ventities.read(from, end); } else { v.ventities = MTPVector(); } @@ -23378,7 +23674,7 @@ inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vpts.read(from, end); v.vpts_count.read(from, end); v.vdate.read(from, end); - if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); } + if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPPeer(); } if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); } if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); } if (v.has_entities()) { v.ventities.read(from, end); } else { v.ventities = MTPVector(); } @@ -23514,10 +23810,10 @@ inline MTPupdates::MTPupdates(MTPDupdateShortSentMessage *_data) : mtpDataOwner( inline MTPupdates MTP_updatesTooLong() { return MTPupdates(mtpc_updatesTooLong); } -inline MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) { +inline MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) { return MTPupdates(new MTPDupdateShortMessage(_flags, _id, _user_id, _message, _pts, _pts_count, _date, _fwd_from_id, _fwd_date, _reply_to_msg_id, _entities)); } -inline MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) { +inline MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, const MTPVector &_entities) { return MTPupdates(new MTPDupdateShortChatMessage(_flags, _id, _from_id, _chat_id, _message, _pts, _pts_count, _date, _fwd_from_id, _fwd_date, _reply_to_msg_id, _entities)); } inline MTPupdates MTP_updateShort(const MTPUpdate &_update, MTPint _date) { @@ -27071,6 +27367,68 @@ inline MTPcontacts_resolvedPeer MTP_contacts_resolvedPeer(const MTPPeer &_peer, return MTPcontacts_resolvedPeer(new MTPDcontacts_resolvedPeer(_peer, _chats, _users)); } +inline MTPchannelParticipant::MTPchannelParticipant() : mtpDataOwner(new MTPDchannelParticipant()) { +} + +inline uint32 MTPchannelParticipant::innerLength() const { + const MTPDchannelParticipant &v(c_channelParticipant()); + return v.vuser_id.innerLength() + v.vinviter_id.innerLength() + v.vdate.innerLength(); +} +inline mtpTypeId MTPchannelParticipant::type() const { + return mtpc_channelParticipant; +} +inline void MTPchannelParticipant::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { + if (cons != mtpc_channelParticipant) throw mtpErrorUnexpected(cons, "MTPchannelParticipant"); + + if (!data) setData(new MTPDchannelParticipant()); + MTPDchannelParticipant &v(_channelParticipant()); + v.vuser_id.read(from, end); + v.vinviter_id.read(from, end); + v.vdate.read(from, end); +} +inline void MTPchannelParticipant::write(mtpBuffer &to) const { + const MTPDchannelParticipant &v(c_channelParticipant()); + v.vuser_id.write(to); + v.vinviter_id.write(to); + v.vdate.write(to); +} +inline MTPchannelParticipant::MTPchannelParticipant(MTPDchannelParticipant *_data) : mtpDataOwner(_data) { +} +inline MTPchannelParticipant MTP_channelParticipant(MTPint _user_id, MTPint _inviter_id, MTPint _date) { + return MTPchannelParticipant(new MTPDchannelParticipant(_user_id, _inviter_id, _date)); +} + +inline MTPmessages_channelParticipants::MTPmessages_channelParticipants() : mtpDataOwner(new MTPDmessages_channelParticipants()) { +} + +inline uint32 MTPmessages_channelParticipants::innerLength() const { + const MTPDmessages_channelParticipants &v(c_messages_channelParticipants()); + return v.vcount.innerLength() + v.vparticipants.innerLength() + v.vusers.innerLength(); +} +inline mtpTypeId MTPmessages_channelParticipants::type() const { + return mtpc_messages_channelParticipants; +} +inline void MTPmessages_channelParticipants::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { + if (cons != mtpc_messages_channelParticipants) throw mtpErrorUnexpected(cons, "MTPmessages_channelParticipants"); + + if (!data) setData(new MTPDmessages_channelParticipants()); + MTPDmessages_channelParticipants &v(_messages_channelParticipants()); + v.vcount.read(from, end); + v.vparticipants.read(from, end); + v.vusers.read(from, end); +} +inline void MTPmessages_channelParticipants::write(mtpBuffer &to) const { + const MTPDmessages_channelParticipants &v(c_messages_channelParticipants()); + v.vcount.write(to); + v.vparticipants.write(to); + v.vusers.write(to); +} +inline MTPmessages_channelParticipants::MTPmessages_channelParticipants(MTPDmessages_channelParticipants *_data) : mtpDataOwner(_data) { +} +inline MTPmessages_channelParticipants MTP_messages_channelParticipants(MTPint _count, const MTPVector &_participants, const MTPVector &_users) { + return MTPmessages_channelParticipants(new MTPDmessages_channelParticipants(_count, _participants, _users)); +} + // Human-readable text serialization #if (defined _DEBUG || defined _WITH_DEBUG) diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 6423ffb41..ad6321462 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -216,7 +216,7 @@ userStatusLastWeek#7bf09fc = UserStatus; userStatusLastMonth#77ebc742 = UserStatus; chatEmpty#9ba2d800 id:int = Chat; -chat#c7c02794 id:int title:string photo:ChatPhoto participants_count:int date:int version:int = Chat; +chat#7312bc48 flags:# id:int title:string photo:ChatPhoto participants_count:int date:int version:int = Chat; chatForbidden#7328bdb id:int title:string = Chat; channel#1bcc63f2 flags:# id:int access_hash:long title:string username:flags.2?string photo:ChatPhoto date:int version:int = Chat; channelForbidden#2d85832c id:int access_hash:long title:string = Chat; @@ -228,12 +228,13 @@ chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant; chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?ChatParticipant = ChatParticipants; chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector version:int = ChatParticipants; +channelParticipants#b561ad0c flags:# channel_id:int self_participant:flags.0?ChatParticipant = ChatParticipants; chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto; messageEmpty#83e5de54 id:int = Message; -message#ab406723 flags:# id:int from_id:flags.8?int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector = Message; +message#5ba66c13 flags:# id:int from_id:flags.8?int to_id:Peer fwd_from_id:flags.2?Peer fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int = Message; messageService#c06b9607 flags:# id:int from_id:flags.8?int to_id:Peer date:int action:MessageAction = Message; messageMediaEmpty#3ded6320 = MessageMedia; @@ -389,8 +390,8 @@ updates.difference#f49ca0 new_messages:Vector new_encrypted_messages:Ve updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector intermediate_state:updates.State = updates.Difference; updatesTooLong#e317af7e = Updates; -updateShortMessage#3f32d858 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; -updateShortChatMessage#f9409b3d flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; +updateShortMessage#f7d91a46 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; +updateShortChatMessage#cac7fdd2 flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?Peer fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; updateShort#78d4dec1 update:Update date:int = Updates; updatesCombined#725b04c3 updates:Vector users:Vector chats:Vector date:int seq_start:int seq:int = Updates; updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; @@ -598,6 +599,10 @@ channelMessagesFilterCollapsed#fa01232e = ChannelMessagesFilter; contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector users:Vector = contacts.ResolvedPeer; +channelParticipant#506116ea user_id:int inviter_id:int date:int = ChannelParticipant; + +messages.channelParticipants#d6891de1 count:int participants:Vector users:Vector = messages.ChannelParticipants; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -675,7 +680,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; messages.sendMessage#fa88427a flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Updates; messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; -messages.forwardMessages#55e1728d peer:InputPeer id:Vector random_id:Vector = Updates; +messages.forwardMessages#f9adea76 from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getChats#27ae65b id:Vector = messages.Chats; messages.getFullChat#36a4dfe chat_id:InputChat = messages.ChatFull; @@ -712,7 +717,10 @@ messages.getImportantHistory#24af43a5 peer:InputPeer offset_id:int add_offset:in messages.readChannelHistory#36a1210e peer:InputPeer max_id:int = Bool; messages.createChannel#e830f8cb flags:# title:string users:Vector = Updates; messages.deleteChannelMessages#9995a84f peer:InputPeer id:Vector = messages.AffectedMessages; +messages.getChannelMessages#5f46b265 peer:InputPeer id:Vector = messages.Messages; +messages.incrementMessagesViews#91ffd479 peer:InputPeer id:Vector = Bool; messages.editChatAbout#8a969b93 chat_id:InputChat about:string = Bool; +messages.getChannelParticipants#4a771976 chat_id:InputChat offset:int limit:int = messages.ChannelParticipants; messages.checkChannelUsername#e6d2d8f4 chat_id:InputChat username:string = Bool; messages.updateChannelUsername#ce2e9587 chat_id:InputChat username:string = Bool; @@ -735,4 +743,4 @@ help.getAppUpdate#c812ac7e device_model:string system_version:string app_version help.saveAppLog#6f02f748 events:Vector = Bool; help.getInviteText#a4a95186 lang_code:string = help.InviteText; help.getSupport#9cdf08cd = help.Support; -help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog; \ No newline at end of file +help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 029a8cef1..a20238425 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -309,7 +309,8 @@ void ProfileInner::blockDone(bool blocked, const MTPBool &result) { bool ProfileInner::blockFail(const RPCError &error) { if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; - //_blockRequest = 0; + + _blockRequest = 0; return false; } diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 845ca5e2a..3fbd37a5c 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -289,12 +289,16 @@ void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix [notification setTitle:QNSString(title).s()]; [notification setSubtitle:QNSString(subtitle).s()]; [notification setInformativeText:QNSString(msg).s()]; - [notification setContentImage:img]; + if ([notification respondsToSelector:@selector(setContentImage:)]) { + [notification setContentImage:img]; + } - if (withReply) [notification setHasReplyButton:YES]; + if (withReply && [notification respondsToSelector:@selector(setHasReplyButton:)]) { + [notification setHasReplyButton:YES]; + } [notification setSoundName:nil]; - + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; [center deliverNotification:notification]; diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 78790d5f0..f7412a36c 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -160,6 +160,8 @@ float64 gSongVolume = 0.9; SavedPeers gSavedPeers; SavedPeersByTime gSavedPeersByTime; +ReportSpamStatuses gReportSpamStatuses; + void settingsParseArgs(int argc, char *argv[]) { #ifdef Q_OS_MAC if (QSysInfo::macVersion() < QSysInfo::MV_10_8) { diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index ad36a2b1b..e2dfa9f42 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -317,4 +317,7 @@ typedef QMultiMap SavedPeersByTime; DeclareRefSetting(SavedPeers, SavedPeers); DeclareRefSetting(SavedPeersByTime, SavedPeersByTime); +typedef QMap ReportSpamStatuses; +DeclareRefSetting(ReportSpamStatuses, ReportSpamStatuses); + void settingsParseArgs(int argc, char *argv[]); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index fb3967a80..898fe92e1 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -329,7 +329,7 @@ public: class ChatData : public PeerData { public: - ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_inputChat(MTP_int(bareId()))), count(0), date(0), version(0), admin(0), left(false), forbidden(true), botStatus(0) { + ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_inputChat(MTP_int(bareId()))), count(0), date(0), version(0), admin(0), inviterForSpamReport(0), left(false), forbidden(true), botStatus(0) { } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); @@ -339,6 +339,7 @@ public: int32 date; int32 version; int32 admin; + int32 inviterForSpamReport; // > 0 - user who invited me to chat in unread service msg, < 0 - have outgoing message bool left; bool forbidden; typedef QMap Participants; diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index c028ee340..db2db5109 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -357,6 +357,13 @@ enum DBIPlatform { dbipLinux32 = 3, }; +enum DBIPeerReportSpamStatus { + dbiprsNoButton, + dbiprsUnknown, + dbiprsShowButton, + dbiprsReportSent, +}; + typedef enum { HitTestNone = 0, HitTestClient, diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 21123feb0..91f38ed05 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -1418,7 +1418,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { HistoryItem *notifyItem = 0; History *notifyHistory = 0; NotifyWaiters::iterator notifyWaiter = notifyWaiters.end(); - for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end(); ++i) { + for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end();) { History *history = i.key(); if (history->currentNotification() && history->currentNotification()->id != i.value().msg) { NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); @@ -1451,6 +1451,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { notifyHistory = history; notifyWaiter = i; } + ++i; } if (notifyItem) { if (next > ms) { @@ -1467,8 +1468,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { uint64 ms = getms(true); History *history = notifyItem->history(); NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - bool notifyWhenFound = (j != notifyWhenMaps.cend()); - if (!notifyWhenFound) { + if (j == notifyWhenMaps.cend()) { history->clearNotifications(); } else { HistoryItem *nextNotify = 0; @@ -1516,7 +1516,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { if (!history->hasNotification()) { if (notifyWaiter != notifyWaiters.cend()) notifyWaiters.erase(notifyWaiter); - if (notifyWhenFound) notifyWhenMaps.erase(j); + notifyWhenMaps.remove(history); continue; } } diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index d2f122b3b..529320931 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.8.55 + 0.8.56 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) CFBundleSignature diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index 1bef96184..ec03f392f 100644 Binary files a/Telegram/Telegram.rc and b/Telegram/Telegram.rc differ diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index ad3a363b0..522b6b901 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1697,7 +1697,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.55; + CURRENT_PROJECT_VERSION = 0.8.56; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1715,7 +1715,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.8.55; + CURRENT_PROJECT_VERSION = 0.8.56; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1741,10 +1741,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.55; + CURRENT_PROJECT_VERSION = 0.8.56; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.55; + DYLIB_CURRENT_VERSION = 0.8.56; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -1875,10 +1875,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.55; + CURRENT_PROJECT_VERSION = 0.8.56; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.55; + DYLIB_CURRENT_VERSION = 0.8.56; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; diff --git a/Telegram/Version.sh b/Telegram/Version.sh index 5ad51f6bd..873248d22 100755 --- a/Telegram/Version.sh +++ b/Telegram/Version.sh @@ -1,2 +1,2 @@ -echo 0.8 8055 0.8.55 0 +echo 0.8 8056 0.8.56 0 # AppVersionStrMajor AppVersion AppVersionStr DevChannel diff --git a/Telegram/_openal_patch.diff b/Telegram/_openal_patch.diff index 951e0e1c0..5eda24496 100644 --- a/Telegram/_openal_patch.diff +++ b/Telegram/_openal_patch.diff @@ -12,7 +12,7 @@ index cfd12d8..8a6f9fb 100644 return ALC_FALSE; } diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c -index 03805ab..77212c2 100644 +index 03805ab..5035a36 100644 --- a/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c @@ -220,7 +220,7 @@ FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg) @@ -20,7 +20,7 @@ index 03805ab..77212c2 100644 althrd_setname(althrd_current(), MIXER_THREAD_NAME); - while(GetMessage(&msg, NULL, 0, 0)) -+ if (!self->killNow) while (GetMessage(&msg, NULL, 0, 0)) ++ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WOM_DONE) continue; @@ -29,7 +29,7 @@ index 03805ab..77212c2 100644 althrd_setname(althrd_current(), RECORD_THREAD_NAME); - while(GetMessage(&msg, NULL, 0, 0)) -+ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0)) ++ if (!self->killNow) while (GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WIM_DATA) continue;