diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 5999c47f4f..d06880d617 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -2074,6 +2074,7 @@ minPhotoSize: 100px; maxMediaSize: 420px; maxStickerSize: 256px; maxGifSize: 320px; +maxSignatureSize: 144px; mvBgColor: #222; mvBgOpacity: 0.92; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index d196f32493..22cad42f6e 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1654,7 +1654,7 @@ namespace App { return i.value(); } - ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type, const QString &url) { + ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type) { ImageLinksData::const_iterator i = imageLinksData.constFind(imageLink); ImageLinkData *result; if (i == imageLinksData.cend()) { diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 760ea77805..2f4144e85f 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -134,7 +134,7 @@ namespace App { WebPageData *webPage(const WebPageId &webPage); WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill); ImageLinkData *imageLink(const QString &imageLink); - ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type, const QString &url); + ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type); void forgetMedia(); MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index f9c77dfc0f..b414fdb399 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -925,7 +925,9 @@ void AppClass::checkLocalTime() { void AppClass::onAppStateChanged(Qt::ApplicationState state) { checkLocalTime(); - _window->updateIsActive((state == Qt::ApplicationActive) ? cOnlineFocusTimeout() : cOfflineBlurTimeout()); + if (_window) { + _window->updateIsActive((state == Qt::ApplicationActive) ? cOnlineFocusTimeout() : cOfflineBlurTimeout()); + } if (state != Qt::ApplicationActive) { PopupTooltip::Hide(); } diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index 8b756c4ee4..65fdd9b32a 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -29,9 +29,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" -StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : -_loaded(false), _setId(0), _setAccess(0), _setCount(0), _setHash(0), _setFlags(0), _bottom(0), -_input(set), _installRequest(0) { +StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget() +, _loaded(false) +, _setId(0) +, _setAccess(0) +, _setCount(0) +, _setHash(0) +, _setFlags(0) +, _bottom(0) +, _input(set) +, _installRequest(0) +, _previewShown(-1) { connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); switch (set.type()) { case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break; @@ -39,6 +47,9 @@ _input(set), _installRequest(0) { } MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet)); App::main()->updateStickers(); + + _previewTimer.setSingleShot(true); + connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview())); } void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) { @@ -148,6 +159,47 @@ bool StickerSetInner::installFailed(const RPCError &error) { return true; } +void StickerSetInner::mousePressEvent(QMouseEvent *e) { + int32 index = stickerFromGlobalPos(e->globalPos()); + if (index >= 0 && index < _pack.size()) { + _previewTimer.start(QApplication::startDragTime()); + } +} + +void StickerSetInner::mouseMoveEvent(QMouseEvent *e) { + if (_previewShown >= 0) { + int32 index = stickerFromGlobalPos(e->globalPos()); + if (index >= 0 && index < _pack.size() && index != _previewShown) { + _previewShown = index; + Ui::showStickerPreview(_pack.at(_previewShown)); + } + } +} + +void StickerSetInner::mouseReleaseEvent(QMouseEvent *e) { + _previewTimer.stop(); +} + +void StickerSetInner::onPreview() { + int32 index = stickerFromGlobalPos(QCursor::pos()); + if (index >= 0 && index < _pack.size()) { + _previewShown = index; + Ui::showStickerPreview(_pack.at(_previewShown)); + } +} + +int32 StickerSetInner::stickerFromGlobalPos(const QPoint &p) const { + QPoint l(mapFromGlobal(p)); + if (rtl()) l.setX(width() - l.x()); + int32 row = (l.y() >= st::stickersPadding.top()) ? qFloor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : -1; + int32 col = (l.x() >= st::stickersPadding.left()) ? qFloor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : -1; + if (row >= 0 && col >= 0 && col < StickerPanPerRow) { + int32 result = row * StickerPanPerRow + col; + return (result < _pack.size()) ? result : -1; + } + return -1; +} + void StickerSetInner::paintEvent(QPaintEvent *e) { QRect r(e->rect()); Painter p(this); diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index d2fd4749ee..356fd4b60f 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.h +++ b/Telegram/SourceFiles/boxes/stickersetbox.h @@ -29,7 +29,9 @@ public: StickerSetInner(const MTPInputStickerSet &set); - void init(); + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); void paintEvent(QPaintEvent *e); @@ -42,10 +44,12 @@ public: void setScrollBottom(int32 bottom); void install(); - QString getTitle() const; - ~StickerSetInner(); +public slots: + + void onPreview(); + signals: void updateButtons(); @@ -53,6 +57,8 @@ signals: private: + int32 stickerFromGlobalPos(const QPoint &p) const; + void gotSet(const MTPmessages_StickerSet &set); bool failedSet(const RPCError &error); @@ -70,6 +76,9 @@ private: MTPInputStickerSet _input; mtpRequestId _installRequest; + + QTimer _previewTimer; + int32 _previewShown; }; class StickerSetBox : public ScrollableBox, public RPCSender { diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 737e70d0b6..0241da6b79 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -3852,8 +3852,12 @@ MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *mrows, Hasht , _stickersPerRow(1) , _recentInlineBotsInRows(0) , _sel(-1) +, _down(-1) , _mouseSel(false) -, _overDelete(false) { +, _overDelete(false) +, _previewShown(false) { + _previewTimer.setSingleShot(true); + connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview())); } void MentionsInner::paintEvent(QPaintEvent *e) { @@ -4030,9 +4034,13 @@ void MentionsInner::mouseMoveEvent(QMouseEvent *e) { onUpdateSelected(true); } -void MentionsInner::clearSel() { +void MentionsInner::clearSel(bool hidden) { _mouseSel = _overDelete = false; setSel((_mrows->isEmpty() && _brows->isEmpty() && _hrows->isEmpty()) ? -1 : 0); + if (hidden) { + _down = -1; + _previewShown = false; + } } bool MentionsInner::moveSel(int key) { @@ -4140,12 +4148,35 @@ void MentionsInner::mousePressEvent(QMouseEvent *e) { _mouseSel = true; onUpdateSelected(true); - } else { + } else if (_srows->isEmpty()) { select(); + } else { + _down = _sel; + _previewTimer.start(QApplication::startDragTime()); } } } +void MentionsInner::mouseReleaseEvent(QMouseEvent *e) { + _previewTimer.stop(); + + int32 pressed = _down; + _down = -1; + + _mousePos = mapToGlobal(e->pos()); + _mouseSel = true; + onUpdateSelected(true); + + if (_previewShown) { + _previewShown = false; + return; + } + + if (_sel < 0 || _sel != pressed || _srows->isEmpty()) return; + + select(); +} + void MentionsInner::enterEvent(QEvent *e) { setMouseTracking(true); _mousePos = QCursor::pos(); @@ -4189,6 +4220,8 @@ void MentionsInner::onUpdateSelected(bool force) { QPoint mouse(mapFromGlobal(_mousePos)); if ((!force && !rect().contains(mouse)) || !_mouseSel) return; + if (_down >= 0 && !_previewShown) return; + int32 sel = -1, maxSel = 0; if (!_srows->isEmpty()) { int32 rows = rowscount(_srows->size(), _stickersPerRow); @@ -4209,6 +4242,12 @@ void MentionsInner::onUpdateSelected(bool force) { } if (sel != _sel) { setSel(sel); + if (_down >= 0 && _sel >= 0 && _down != _sel) { + _down = _sel; + if (_down >= 0 && _down < _srows->size()) { + Ui::showStickerPreview(_srows->at(_down)); + } + } } } @@ -4220,6 +4259,13 @@ void MentionsInner::onParentGeometryChanged() { } } +void MentionsInner::onPreview() { + if (_down >= 0 && _down < _srows->size()) { + Ui::showStickerPreview(_srows->at(_down)); + _previewShown = true; + } +} + MentionsDropdown::MentionsDropdown(QWidget *parent) : TWidget(parent) , _scroll(this, st::mentionScroll) , _inner(this, &_mrows, &_hrows, &_brows, &_srows) @@ -4569,7 +4615,7 @@ void MentionsDropdown::hideFinish() { hide(); _hiding = false; _filter = qsl("-"); - _inner.clearSel(); + _inner.clearSel(true); } void MentionsDropdown::showStart() { diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index 5ff587a236..bacf6149c1 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -744,8 +744,9 @@ public: void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); - void clearSel(); + void clearSel(bool hidden = false); bool moveSel(int key); bool select(); @@ -763,6 +764,7 @@ public slots: void onParentGeometryChanged(); void onUpdateSelected(bool force = false); + void onPreview(); private: @@ -775,11 +777,15 @@ private: BotCommandRows *_brows; StickerPack *_srows; int32 _stickersPerRow, _recentInlineBotsInRows; - int32 _sel; + int32 _sel, _down; bool _mouseSel; QPoint _mousePos; bool _overDelete; + + bool _previewShown; + + QTimer _previewTimer; }; class MentionsDropdown : public TWidget { diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index e6b3c22f0a..d65081f517 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -44,8 +44,8 @@ namespace App { if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0); } - void openPeerByName(const QString &username, bool toProfile, const QString &startToken) { - if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken); + void openPeerByName(const QString &username, MsgId msgId, const QString &startToken) { + if (MainWidget *m = main()) m->openPeerByName(username, msgId, startToken); } void joinGroupByHash(const QString &hash) { @@ -90,11 +90,15 @@ namespace App { namespace Ui { void showStickerPreview(DocumentData *sticker) { - if (MainWidget *m = App::main()) m->ui_showStickerPreview(sticker); + if (Window *w = App::wnd()) { + w->ui_showStickerPreview(sticker); + } } void hideStickerPreview() { - if (MainWidget *m = App::main()) m->ui_hideStickerPreview(); + if (Window *w = App::wnd()) { + w->ui_hideStickerPreview(); + } } void showLayer(LayeredWidget *box, ShowLayerOptions options) { diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 328773f2de..e89c2da180 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -27,7 +27,7 @@ namespace App { void sendBotCommand(const QString &cmd, MsgId replyTo = 0); bool insertBotCommand(const QString &cmd, bool specialGif = false); void searchByHashtag(const QString &tag, PeerData *inPeer); - void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString()); + void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString()); void joinGroupByHash(const QString &hash); void stickersBox(const QString &name); void openLocalUrl(const QString &url); diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index 00f31d3041..6e7a772c8b 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -914,19 +914,22 @@ void TextLink::onClick(Qt::MouseButton button) const { PopupTooltip::Hide(); QString url = TextLink::encoded(); - QRegularExpressionMatch telegramMeUser = QRegularExpression(qsl("^https?://telegram\\.me/([a-zA-Z0-9\\.\\_]+)/?(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url); + QRegularExpressionMatch telegramMeUser = QRegularExpression(qsl("^https?://telegram\\.me/([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), QRegularExpression::CaseInsensitiveOption).match(url); QRegularExpressionMatch telegramMeGroup = QRegularExpression(qsl("^https?://telegram\\.me/joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url); QRegularExpressionMatch telegramMeStickers = QRegularExpression(qsl("^https?://telegram\\.me/addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url); QRegularExpressionMatch telegramMeShareUrl = QRegularExpression(qsl("^https?://telegram\\.me/share/url\\?(.+)$"), QRegularExpression::CaseInsensitiveOption).match(url); - if (telegramMeUser.hasMatch()) { - QString params = url.mid(telegramMeUser.captured(0).size()); - url = qsl("tg://resolve/?domain=") + myUrlEncode(telegramMeUser.captured(1)) + (params.isEmpty() ? QString() : '&' + params); - } else if (telegramMeGroup.hasMatch()) { + if (telegramMeGroup.hasMatch()) { url = qsl("tg://join?invite=") + myUrlEncode(telegramMeGroup.captured(1)); } else if (telegramMeStickers.hasMatch()) { url = qsl("tg://addstickers?set=") + myUrlEncode(telegramMeStickers.captured(1)); } else if (telegramMeShareUrl.hasMatch()) { url = qsl("tg://msg_url?") + telegramMeShareUrl.captured(1); + } else if (telegramMeUser.hasMatch()) { + QString params = url.mid(telegramMeUser.captured(0).size()), postParam; + if (QRegularExpression(qsl("^/\\d+/?(?:\\?|$)")).match(telegramMeUser.captured(2)).hasMatch()) { + postParam = qsl("&post=") + telegramMeUser.captured(3); + } + url = qsl("tg://resolve/?domain=") + myUrlEncode(telegramMeUser.captured(1)) + postParam + (params.isEmpty() ? QString() : '&' + params); } if (QRegularExpression(qsl("^tg://[a-zA-Z0-9]+"), QRegularExpression::CaseInsensitiveOption).match(url).hasMatch()) { @@ -951,6 +954,17 @@ void CustomTextLink::onClick(Qt::MouseButton button) const { Ui::showLayer(new ConfirmLinkBox(text())); } +void LocationLink::onClick(Qt::MouseButton button) const { + if (!psLaunchMaps(_lat, _lon)) { + QDesktopServices::openUrl(_text); + } +} + +void LocationLink::setup() { + QString latlon = _lat + ',' + _lon; + _text = qsl("https://maps.google.com/maps?q=") + latlon + qsl("&ll=") + latlon + qsl("&z=16"); +} + 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 1312bc759f..341ebb9034 100644 --- a/Telegram/SourceFiles/gui/text.h +++ b/Telegram/SourceFiles/gui/text.h @@ -374,7 +374,7 @@ public: QUrl u(_url), good(u.isValid() ? u.toEncoded() : QString()); QString result(good.isValid() ? QString::fromUtf8(good.toEncoded()) : _url); - if (!QRegularExpression(qsl("^[a-zA-Z]+://")).match(result).hasMatch()) { // no protocol + if (!QRegularExpression(qsl("^[a-zA-Z]+:")).match(result).hasMatch()) { // no protocol return qsl("http://") + result; } return result; @@ -423,6 +423,36 @@ private: }; +class LocationLink : public ITextLink { + TEXT_LINK_CLASS(LocationLink) + +public: + + LocationLink(const QString &lat, const QString &lon) : _lat(lat), _lon(lon) { + setup(); + } + + const QString &text() const { + return _text; + } + + void onClick(Qt::MouseButton button) const; + + const QString &readable() const { + return _text; + } + + QString encoded() const { + return _text; + } + +private: + + void setup(); + QString _lat, _lon, _text; + +}; + class MentionLink : public ITextLink { TEXT_LINK_CLASS(MentionLink) diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index e64facc5b4..eeda88bf71 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -88,10 +88,10 @@ namespace { return item ? item->toHistoryForwarded() : 0; } inline const TextParseOptions &itemTextOptions(HistoryItem *item) { - return itemTextOptions(item->history(), item->from()); + return itemTextOptions(item->history(), item->author()); } inline const TextParseOptions &itemTextNoMonoOptions(const HistoryItem *item) { - return itemTextNoMonoOptions(item->history(), item->from()); + return itemTextNoMonoOptions(item->history(), item->author()); } } @@ -1385,7 +1385,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org"))); EntitiesInText entities = textParseEntities(text, _historyTextNoMonoOptions.flags); entities.push_front(EntityInText(EntityInTextItalic, 0, text.size())); - result = new HistoryMessage(this, block, m.vid.v, m.vflags.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, text, entities, 0); + result = new HistoryMessage(this, block, m.vid.v, m.vflags.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, text, entities, -1, 0); } else if (badMedia) { result = new HistoryServiceMsg(this, block, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, 0, m.has_from_id() ? m.vfrom_id.v : 0); } else { @@ -1532,8 +1532,8 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo return regItem(result); } -HistoryItem *History::createItemForwarded(HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg) { - return regItem(new HistoryForwarded(this, block, id, date, from, msg)); +HistoryItem *History::createItemForwarded(HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg) { + return regItem(new HistoryForwarded(this, block, id, flags, date, from, msg)); } HistoryItem *History::createItemDocument(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { @@ -1609,7 +1609,7 @@ HistoryItem *History::addToHistory(const MTPMessage &msg) { return createItem(0, msg, false); } -HistoryItem *History::addNewForwarded(MsgId id, QDateTime date, int32 from, HistoryMessage *item) { +HistoryItem *History::addNewForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *item) { HistoryBlock *to = 0; bool newBlock = blocks.isEmpty(); if (newBlock) { @@ -1617,7 +1617,7 @@ HistoryItem *History::addNewForwarded(MsgId id, QDateTime date, int32 from, Hist } else { to = blocks.back(); } - return addNewItem(to, newBlock, createItemForwarded(to, id, date, from, item), true); + return addNewItem(to, newBlock, createItemForwarded(to, id, flags, date, from, item), true); } HistoryItem *History::addNewDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { @@ -1823,7 +1823,9 @@ void History::unregTyping(UserData *from) { void History::newItemAdded(HistoryItem *item) { App::checkImageCacheSize(); if (item->from() && item->from()->isUser()) { - unregTyping(item->from()->asUser()); + if (item->from() == item->author()) { + unregTyping(item->from()->asUser()); + } item->from()->asUser()->madeAction(); } if (item->out()) { @@ -2001,28 +2003,30 @@ void History::addOlderSlice(const QVector &slice, const QVectorauthor()->id) { if (markupSenders) { // chats with bots if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { int32 markupFlags = App::replyMarkup(channelId(), item->id).flags; if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) { - bool wasKeyboardHide = markupSenders->contains(item->from()); + bool wasKeyboardHide = markupSenders->contains(item->author()); if (!wasKeyboardHide) { - markupSenders->insert(item->from(), true); + markupSenders->insert(item->author(), true); } if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) { if (!lastKeyboardInited) { bool botNotInChat = false; if (peer->isChat()) { - botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser()); + botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->author()->isUser() && !peer->asChat()->participants.contains(item->author()->asUser()); } else if (peer->isMegagroup()) { - botNotInChat = (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && item->from()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->from()->asUser()); + botNotInChat = (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && item->author()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->author()->asUser()); } if (wasKeyboardHide || botNotInChat) { clearLastKeyboard(); } else { lastKeyboardInited = true; lastKeyboardId = item->id; - lastKeyboardFrom = item->from()->id; + lastKeyboardFrom = item->author()->id; lastKeyboardUsed = false; } } @@ -2037,7 +2041,7 @@ void History::addOlderSlice(const QVector &slice, const QVectorid; - lastKeyboardFrom = item->from()->id; + lastKeyboardFrom = item->author()->id; lastKeyboardUsed = false; } } @@ -2828,7 +2832,7 @@ void HistoryBlock::removeItem(HistoryItem *item) { dh = item->height(); items.remove(i); int32 l = items.size(); - if ((!item->out() || item->fromChannel()) && item->unread() && history->unreadCount) { + if ((!item->out() || item->isPost()) && item->unread() && history->unreadCount) { history->setUnreadCount(history->unreadCount - 1); } int32 itemType = item->type(); @@ -2856,11 +2860,10 @@ HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int , id(msgId) , date(msgDate) , _from(from ? App::user(from) : history->peer) -, _fromVersion(_from->nameVersion) , _history(history) , _block(block) , _flags(flags) -{ +, _authorNameVersion(author()->nameVersion) { } void HistoryItem::destroy() { @@ -2913,7 +2916,7 @@ void HistoryItem::setId(MsgId newId) { } bool HistoryItem::displayFromPhoto() const { - return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !fromChannel(); + return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost(); } void HistoryItem::clipCallback(ClipReaderNotification notification) { @@ -3280,7 +3283,7 @@ void HistoryPhoto::draw(Painter &p, const HistoryItem *parent, const QRect &r, b bool notChild = (parent->getMedia() == this); int32 skipx = 0, skipy = 0, width = _width, height = _height; bool bubble = parent->hasBubble(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 captionw = width - st::msgPadding.left() - st::msgPadding.right(); @@ -3362,7 +3365,7 @@ void HistoryPhoto::draw(Painter &p, const HistoryItem *parent, const QRect &r, b // date if (_caption.isEmpty()) { - if (notChild) { + if (notChild && (_data->uploading() || App::hoveredItem() == parent)) { int32 fullRight = skipx + width, fullBottom = skipy + height; parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, InfoDisplayOverImage); } @@ -3589,7 +3592,7 @@ void HistoryVideo::draw(Painter &p, const HistoryItem *parent, const QRect &r, b int32 skipx = 0, skipy = 0, width = _width, height = _height; bool bubble = parent->hasBubble(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 captionw = width - st::msgPadding.left() - st::msgPadding.right(); @@ -3829,11 +3832,11 @@ HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedi } void HistoryDocument::create(bool caption) { - uint64 mask; + uint64 mask = 0; if (_data->voice()) { - mask = HistoryDocumentVoice::Bit(); + mask |= HistoryDocumentVoice::Bit(); } else { - mask = HistoryDocumentNamed::Bit(); + mask |= HistoryDocumentNamed::Bit(); if (caption) { mask |= HistoryDocumentCaptioned::Bit(); } @@ -3924,7 +3927,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r int32 captionw = _width - st::msgPadding.left() - st::msgPadding.right(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; if (displayLoading) { ensureAnimation(parent); @@ -4139,7 +4142,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const { if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; bool loaded = _data->loaded(); bool showPause = updateStatusText(parent); @@ -4508,7 +4511,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo int32 skipx = 0, skipy = 0, width = _width, height = _height; bool bubble = parent->hasBubble(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 captionw = width - st::msgPadding.left() - st::msgPadding.right(); @@ -4789,13 +4792,13 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, _data->checkSticker(); bool loaded = _data->loaded(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel, hovered, pressed; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost, hovered, pressed; int32 usew = _maxw, usex = 0; const HistoryReply *reply = toHistoryReply(parent); if (reply) { usew -= st::msgReplyPadding.left() + reply->replyToWidth(); - if (fromChannel) { + if (isPost) { } else if (out) { usex = _width - usew; } @@ -4821,7 +4824,7 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, if (reply) { int32 rw = _width - usew - st::msgReplyPadding.left(), rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - int32 rx = fromChannel ? (usew + st::msgReplyPadding.left()) : (out ? 0 : (usew + st::msgReplyPadding.left())), ry = _height - rh; + int32 rx = isPost ? (usew + st::msgReplyPadding.left()) : (out ? 0 : (usew + st::msgReplyPadding.left())), ry = _height - rh; if (rtl()) rx = _width - rx - rw; App::roundRect(p, rx, ry, rw, rh, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? ServiceSelectedCorners : ServiceCorners); @@ -4834,13 +4837,13 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, void HistorySticker::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const { if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 usew = _maxw, usex = 0; const HistoryReply *reply = toHistoryReply(parent); if (reply) { usew -= reply->replyToWidth(); - if (fromChannel) { + if (isPost) { } else if (out) { usex = _width - usew; } @@ -4848,7 +4851,7 @@ void HistorySticker::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 if (rtl()) usex = _width - usex - usew; if (reply) { int32 rw = _width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); - int32 rx = fromChannel ? (usew + st::msgReplyPadding.left()) : (out ? 0 : (usew + st::msgReplyPadding.left())), ry = _height - rh; + int32 rx = isPost ? (usew + st::msgReplyPadding.left()) : (out ? 0 : (usew + st::msgReplyPadding.left())), ry = _height - rh; if (rtl()) rx = _width - rx - rw; if (x >= rx && y >= ry && x < rx + rw && y < ry + rh) { lnk = reply->replyToLink(); @@ -4964,7 +4967,7 @@ void HistoryContact::draw(Painter &p, const HistoryItem *parent, const QRect &r, if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; int32 skipx = 0, skipy = 0, width = _width, height = _height; - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; if (width >= _maxw) { width = _maxw; @@ -5015,7 +5018,7 @@ void HistoryContact::draw(Painter &p, const HistoryItem *parent, const QRect &r, } void HistoryContact::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const { - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; if (_userId) { @@ -5341,7 +5344,7 @@ void HistoryWebPage::draw(Painter &p, const HistoryItem *parent, const QRect &r, if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; int32 skipx = 0, skipy = 0, width = _width, height = _height; - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; style::color barfg = (selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor)); style::color semibold = (selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); @@ -5745,11 +5748,10 @@ _description(st::msgMinWidth) { _description.setText(st::webPageDescriptionFont, textClean(description), _webpageDescriptionOptions); } - if (url.startsWith(qsl("location:"))) { - QString lnk = qsl("https://maps.google.com/maps?q=") + url.mid(9) + qsl("&ll=") + url.mid(9) + qsl("&z=17"); - _link.reset(new TextLink(lnk)); - - _data = App::imageLinkSet(url, GoogleMapsLink, lnk); + QRegularExpressionMatch m = QRegularExpression(qsl("^location:(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)$")).match(url); + if (m.hasMatch()) { + _link.reset(new LocationLink(m.captured(1), m.captured(2))); + _data = App::imageLinkSet(url, GoogleMapsLink); } else { _link.reset(new TextLink(url)); } @@ -5831,7 +5833,7 @@ void HistoryImageLink::draw(Painter &p, const HistoryItem *parent, const QRect & if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; int32 skipx = 0, skipy = 0, width = _width, height = _height; bool bubble = parent->hasBubble(); - bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; + bool out = parent->out(), isPost = parent->isPost(), outbg = out && !isPost; if (bubble) { skipx = st::mediaPadding.left(); @@ -5973,18 +5975,24 @@ void ViaInlineBotLink::onClick(Qt::MouseButton button) const { App::insertBotCommand('@' + _bot->username); } -HistoryMessageVia::HistoryMessageVia(int32 userId) -: bot(App::userLoaded(peerFromUser(userId))) +HistoryMessageVia::HistoryMessageVia(Interfaces *) +: bot(0) , width(0) -, maxWidth(bot ? st::msgServiceNameFont->width(lng_inline_bot_via(lt_inline_bot, '@' + bot->username)) : 0) -, lnk(new ViaInlineBotLink(bot)) { +, maxWidth(0) { +} + +void HistoryMessageVia::create(int32 userId) { + if (bot = App::userLoaded(peerFromUser(userId))) { + maxWidth = st::msgServiceNameFont->width(lng_inline_bot_via(lt_inline_bot, '@' + bot->username)); + lnk.reset(new ViaInlineBotLink(bot)); + } } bool HistoryMessageVia::isNull() const { return !bot || bot->username.isEmpty(); } -void HistoryMessageVia::resize(int32 availw) { +void HistoryMessageVia::resize(int32 availw) const { if (availw < 0) { text = QString(); width = 0; @@ -5999,29 +6007,46 @@ void HistoryMessageVia::resize(int32 availw) { } } +HistoryMessageViews::HistoryMessageViews(Interfaces *) +: _views(0) +, _viewsWidth(0) { +} + +HistoryMessageSigned::HistoryMessageSigned(Interfaces *) { +} + +void HistoryMessageSigned::create(UserData *from, const QDateTime &date) { + QString time = qsl(", ") + date.toString(cTimeFormat()), name = App::peerName(from); + int32 timew = st::msgDateFont->width(time), namew = st::msgDateFont->width(name); + if (timew + namew > st::maxSignatureSize) { + name = st::msgDateFont->elided(from->firstName, st::maxSignatureSize - timew); + } + _signature.setText(st::msgDateFont, name + time, _textNameOptions); +} + +int32 HistoryMessageSigned::maxWidth() const { + return _signature.maxWidth(); +} + HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via(msg.has_via_bot_id() ? new HistoryMessageVia(msg.vvia_bot_id.v) : 0) -, _media(0) -, _views(msg.has_views() ? msg.vviews.v : -1) { +, _media(0) { + create(msg.has_via_bot_id() ? msg.vvia_bot_id.v : 0, msg.has_views() ? msg.vviews.v : -1); QString text(textClean(qs(msg.vmessage))); - initTime(); initMedia(msg.has_media() ? (&msg.vmedia) : 0, text); setText(text, msg.has_entities() ? entitiesFromMTP(msg.ventities.c_vector().v) : EntitiesInText()); } -HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities, HistoryMedia *fromMedia) : +HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities, int32 fromViews, HistoryMedia *fromMedia) : HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) -, _media(0) -, _views(fromChannel() ? 1 : -1) { - initTime(); +, _media(0) { + create((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, (fromViews > 0) ? fromViews : (isPost() ? 1 : -1)); if (fromMedia) { _media = fromMedia->clone(); _media->regItem(this); @@ -6034,10 +6059,8 @@ HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_ , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) -, _media(0) -, _views(fromChannel() ? 1 : -1) { - initTime(); +, _media(0) { + create((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); initMediaFromDocument(doc, caption); setText(QString(), EntitiesInText()); } @@ -6047,15 +6070,37 @@ HistoryItem(history, block, msgId, flags, date, (flags & MTPDmessage::flag_from_ , _text(st::msgMinWidth) , _textWidth(0) , _textHeight(0) -, _via((flags & MTPDmessage::flag_via_bot_id) ? new HistoryMessageVia(viaBotId) : 0) -, _media(0) -, _views(fromChannel() ? 1 : -1) { - initTime(); +, _media(0) { + create((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); _media = new HistoryPhoto(photo, caption, this); _media->regItem(this); setText(QString(), EntitiesInText()); } +void HistoryMessage::create(int32 viaBotId, int32 viewsCount) { + uint64 mask = 0; + if (viaBotId) { + mask |= HistoryMessageVia::Bit(); + } + if (viewsCount >= 0) { + mask |= HistoryMessageViews::Bit(); + } + if (isPost() && _from->isUser()) { + mask |= HistoryMessageSigned::Bit(); + } + UpdateInterfaces(mask); + if (HistoryMessageVia *via = Get()) { + via->create(viaBotId); + } + if (HistoryMessageViews *views = Get()) { + views->_views = viewsCount; + } + if (HistoryMessageSigned *msgsigned = Get()) { + msgsigned->create(_from->asUser(), date); + } + initTime(); +} + QString formatViewsCount(int32 views) { if (views > 999999) { views /= 100000; @@ -6076,11 +6121,16 @@ QString formatViewsCount(int32 views) { } void HistoryMessage::initTime() { - _timeText = date.toString(cTimeFormat()); - _timeWidth = st::msgDateFont->width(_timeText); - - _viewsText = (_views >= 0) ? formatViewsCount(_views) : QString(); - _viewsWidth = _viewsText.isEmpty() ? 0 : st::msgDateFont->width(_viewsText); + if (HistoryMessageSigned *msgsigned = Get()) { + _timeWidth = msgsigned->maxWidth(); + } else { + _timeText = date.toString(cTimeFormat()); + _timeWidth = st::msgDateFont->width(_timeText); + } + if (HistoryMessageViews *views = Get()) { + views->_viewsText = (views->_views >= 0) ? formatViewsCount(views->_views) : QString(); + views->_viewsWidth = views->_viewsText.isEmpty() ? 0 : st::msgDateFont->width(views->_viewsText); + } } void HistoryMessage::initMedia(const MTPMessageMedia *media, QString ¤tText) { @@ -6178,7 +6228,7 @@ void HistoryMessage::initDimensions() { } if (!_media) { if (displayFromName()) { - int32 namew = st::msgPadding.left() + _from->nameText.maxWidth() + st::msgPadding.right(); + int32 namew = st::msgPadding.left() + author()->nameText.maxWidth() + st::msgPadding.right(); if (via() && !toHistoryForwarded()) { namew += st::msgServiceFont->spacew + via()->maxWidth; } @@ -6206,7 +6256,7 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { if (Adaptive::Wide()) { hwidth = hmaxwidth; } - left += (!fromChannel() && out() && !Adaptive::Wide()) ? st::msgMargin.right() : st::msgMargin.left(); + left += (!isPost() && out() && !Adaptive::Wide()) ? st::msgMargin.right() : st::msgMargin.left(); if (displayFromPhoto()) { left += st::msgPhotoSkip; // } else if (!Adaptive::Wide() && !out() && !fromChannel() && st::msgPhotoSkip - (hmaxwidth - hwidth) > 0) { @@ -6215,7 +6265,7 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { width = hwidth - st::msgMargin.left() - st::msgMargin.right(); if (width > maxwidth) { - if (!fromChannel() && out() && !Adaptive::Wide()) { + if (!isPost() && out() && !Adaptive::Wide()) { left += width - maxwidth; } width = maxwidth; @@ -6223,10 +6273,10 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { } void HistoryMessage::fromNameUpdated(int32 width) const { - _fromVersion = _from->nameVersion; + _authorNameVersion = author()->nameVersion; if (drawBubble() && displayFromName()) { if (via() && !toHistoryForwarded()) { - via()->resize(width - st::msgPadding.left() - st::msgPadding.right() - _from->nameText.maxWidth() - st::msgServiceFont->spacew); + via()->resize(width - st::msgPadding.left() - st::msgPadding.right() - author()->nameText.maxWidth() - st::msgServiceFont->spacew); } } } @@ -6304,7 +6354,7 @@ void HistoryMessage::setMedia(const MTPMessageMedia *media) { } void HistoryMessage::setText(const QString &text, const EntitiesInText &entities) { - textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle)); + textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); if (_media && _media->isDisplayed()) { _text.setMarkedText(st::msgFont, text, entities, itemTextOptions(this)); } else { @@ -6337,7 +6387,7 @@ bool HistoryMessage::textHasLinks() { void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const { p.setFont(st::msgDateFont); - bool outbg = out() && !fromChannel(), overimg = (type == InfoDisplayOverImage); + bool outbg = out() && !isPost(), overimg = (type == InfoDisplayOverImage); int32 infoRight = right, infoBottom = bottom; switch (type) { case InfoDisplayDefault: @@ -6363,22 +6413,26 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width } dateX += HistoryMessage::timeLeft(); - p.drawText(dateX, dateY + st::msgDateFont->ascent, _timeText); + if (const HistoryMessageSigned *msgsigned = Get()) { + msgsigned->_signature.drawElided(p, dateX, dateY, _timeWidth); + } else { + p.drawText(dateX, dateY + st::msgDateFont->ascent, _timeText); + } QPoint iconPos; const QRect *iconRect = 0; - if (!_viewsText.isEmpty()) { + if (const HistoryMessageViews *views = Get()) { iconPos = QPoint(infoRight - infoW + st::msgViewsPos.x(), infoBottom - st::msgViewsImg.pxHeight() + st::msgViewsPos.y()); if (id > 0) { - if (out() && !fromChannel()) { + if (outbg) { iconRect = &(overimg ? st::msgInvViewsImg : (selected ? st::msgSelectOutViewsImg : st::msgOutViewsImg)); } else { iconRect = &(overimg ? st::msgInvViewsImg : (selected ? st::msgSelectViewsImg : st::msgViewsImg)); } - p.drawText(iconPos.x() + st::msgViewsImg.pxWidth() + st::msgDateCheckSpace, infoBottom - st::msgDateFont->descent, _viewsText); + p.drawText(iconPos.x() + st::msgViewsImg.pxWidth() + st::msgDateCheckSpace, infoBottom - st::msgDateFont->descent, views->_viewsText); } else { - iconPos.setX(iconPos.x() + st::msgDateViewsSpace + _viewsWidth); - if (out() && !fromChannel()) { + iconPos.setX(iconPos.x() + st::msgDateViewsSpace + views->_viewsWidth); + if (outbg) { iconRect = &(overimg ? st::msgInvSendingViewsImg : st::msgSendingOutViewsImg); } else { iconRect = &(overimg ? st::msgInvSendingViewsImg : st::msgSendingViewsImg); @@ -6390,7 +6444,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width iconRect = &(overimg ? st::msgInvSendingViewsImg : st::msgSendingViewsImg); p.drawPixmap(iconPos, App::sprite(), *iconRect); } - if (out() && !fromChannel()) { + if (outbg) { iconPos = QPoint(infoRight - st::msgCheckImg.pxWidth() + st::msgCheckPos.x(), infoBottom - st::msgCheckImg.pxHeight() + st::msgCheckPos.y()); if (id > 0) { if (unread()) { @@ -6406,13 +6460,14 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width } void HistoryMessage::setViewsCount(int32 count, bool reinit) { - if (_views == count || (count >= 0 && _views > count)) return; + HistoryMessageViews *views = Get(); + if (!views || views->_views == count || (count >= 0 && views->_views > count)) return; - int32 was = _viewsWidth; - _views = count; - _viewsText = (_views >= 0) ? formatViewsCount(_views) : QString(); - _viewsWidth = _viewsText.isEmpty() ? 0 : st::msgDateFont->width(_viewsText); - if (was == _viewsWidth) { + int32 was = views->_viewsWidth; + views->_views = count; + views->_viewsText = (views->_views >= 0) ? formatViewsCount(views->_views) : QString(); + views->_viewsWidth = views->_viewsText.isEmpty() ? 0 : st::msgDateFont->width(views->_viewsText); + if (was == views->_viewsWidth) { Ui::repaintHistoryItem(this); } else { if (_text.hasSkipBlock()) { @@ -6444,7 +6499,7 @@ void HistoryMessage::setId(MsgId newId) { } void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const { - bool outbg = out() && !fromChannel(), bubble = drawBubble(), selected = (selection == FullSelection); + bool outbg = out() && !isPost(), bubble = drawBubble(), selected = (selection == FullSelection); textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle)); @@ -6464,13 +6519,13 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m int32 left = 0, width = 0; countPositionAndSize(left, width); - if (_from->nameVersion > _fromVersion) { + if (author()->nameVersion > _authorNameVersion) { fromNameUpdated(width); } if (displayFromPhoto()) { - int32 photoleft = left + ((!fromChannel() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); - p.drawPixmap(photoleft, _height - st::msgMargin.bottom() - st::msgPhotoSize, _from->photo->pixRounded(st::msgPhotoSize)); + int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); + p.drawPixmap(photoleft, _height - st::msgMargin.bottom() - st::msgPhotoSize, author()->photo->pixRounded(st::msgPhotoSize)); } if (width < 1) return; @@ -6484,15 +6539,15 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m if (displayFromName()) { p.setFont(st::msgNameFont); - if (fromChannel()) { + if (isPost()) { p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg); } else { - p.setPen(_from->color); + p.setPen(author()->color); } - _from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right()); - if (via() && !toHistoryForwarded() && width > st::msgPadding.left() + st::msgPadding.right() + _from->nameText.maxWidth() + st::msgServiceFont->spacew) { + author()->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right()); + if (via() && !toHistoryForwarded() && width > st::msgPadding.left() + st::msgPadding.right() + author()->nameText.maxWidth() + st::msgServiceFont->spacew) { p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); - p.drawText(r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew, r.top() + st::msgPadding.top() + st::msgServiceFont->ascent, via()->text); + p.drawText(r.left() + st::msgPadding.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew, r.top() + st::msgPadding.top() + st::msgServiceFont->ascent, via()->text); } r.setTop(r.top() + st::msgNameFont->height); } @@ -6524,7 +6579,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m } void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection) const { - bool outbg = out() && !fromChannel(), selected = (selection == FullSelection); + bool outbg = out() && !isPost(), selected = (selection == FullSelection); if (!displayFromName() && via() && !toHistoryForwarded()) { p.setFont(st::msgServiceNameFont); p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg)); @@ -6564,7 +6619,7 @@ int32 HistoryMessage::resize(int32 width) { } else { int32 textWidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 1); if (textWidth != _textWidth) { - textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle)); + textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); _textWidth = textWidth; _textHeight = _text.countHeight(textWidth); textstyleRestore(); @@ -6637,9 +6692,9 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 int32 left = 0, width = 0; countPositionAndSize(left, width); if (displayFromPhoto()) { - int32 photoleft = left + ((!fromChannel() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); + int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); if (x >= photoleft && x < photoleft + st::msgPhotoSize && y >= _height - st::msgMargin.bottom() - st::msgPhotoSize && y < _height - st::msgMargin.bottom()) { - lnk = _from->lnk; + lnk = author()->lnk; return; } } @@ -6649,11 +6704,11 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); if (displayFromName()) { // from user left name if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height) { - if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth()) { - lnk = _from->lnk; + if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth()) { + lnk = author()->lnk; return; } - if (via() && !toHistoryForwarded() && x >= r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew + via()->width) { + if (via() && !toHistoryForwarded() && x >= r.left() + st::msgPadding.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth() + st::msgServiceFont->spacew + via()->width) { lnk = via()->lnk; return; } @@ -6694,7 +6749,7 @@ void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorStat inDate = HistoryMessage::pointInTime(r.x() + r.width(), r.y() + r.height(), x, y, InfoDisplayDefault); } - textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle)); + textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); bool inText = false; _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width()); textstyleRestore(); @@ -6728,7 +6783,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, trect.setBottom(trect.bottom() - _media->height()); } - textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle)); + textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); _text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width()); textstyleRestore(); } @@ -6738,10 +6793,10 @@ void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const Hi if (cacheFor != this) { cacheFor = this; QString msg(inDialogsText()); - if ((!_history->peer->isUser() || out()) && !fromChannel()) { + if ((!_history->peer->isUser() || out()) && !isPost()) { TextCustomTagsMap custom; custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); - msg = lng_message_with_from(lt_from, textRichPrepare((_from == App::self()) ? lang(lng_from_you) : _from->shortName()), lt_message, textRichPrepare(msg)); + msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg)); cache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom); } else { cache.setText(st::dlgHistFont, msg, _textDlgOptions); @@ -6757,7 +6812,7 @@ void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const Hi } QString HistoryMessage::notificationHeader() const { - return (!_history->peer->isUser() && !fromChannel()) ? from()->name : QString(); + return (!_history->peer->isUser() && !isPost()) ? from()->name : QString(); } QString HistoryMessage::notificationText() const { @@ -6771,7 +6826,6 @@ HistoryMessage::~HistoryMessage() { _media->unregItem(this); deleteAndMark(_media); } - deleteAndMark(_via); if (_flags & MTPDmessage::flag_reply_markup) { App::clearReplyMarkup(channelId(), id); } @@ -6785,8 +6839,8 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const , fromWidth(st::msgServiceFont->width(lang(lng_forwarded_from)) + st::msgServiceFont->spacew) { } -HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg) -: HistoryMessage(history, block, id, newForwardedFlags(history->peer, from, msg), msg->via() ? peerToUser(msg->viaBot()->id) : 0, date, from, msg->HistoryMessage::originalText(), msg->HistoryMessage::originalEntities(), msg->getMedia()) +HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg) +: HistoryMessage(history, block, id, newForwardedFlags(history->peer, from, msg) | flags, msg->via() ? peerToUser(msg->viaBot()->id) : 0, date, from, msg->HistoryMessage::originalText(), msg->HistoryMessage::originalEntities(), msg->HistoryMessage::viewsCount(), msg->getMedia()) , fwdDate(msg->dateForwarded()) , fwdFrom(msg->fromForwarded()) , fwdFromVersion(fwdFrom->nameVersion) @@ -6834,7 +6888,7 @@ void HistoryForwarded::draw(Painter &p, const QRect &r, uint32 selection, uint64 void HistoryForwarded::drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w, bool selected) const { style::font serviceFont(st::msgServiceFont), serviceName(st::msgServiceNameFont); - bool outbg = out() && !fromChannel(); + bool outbg = out() && !isPost(); p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p); p.setFont(serviceFont); @@ -6902,7 +6956,7 @@ void HistoryForwarded::getState(TextLinkPtr &lnk, HistoryCursorState &state, int int32 left = 0, width = 0; countPositionAndSize(left, width); if (displayFromPhoto()) { - int32 photoleft = left + ((!fromChannel() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); + int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); if (x >= photoleft && x < photoleft + st::msgPhotoSize) { return HistoryMessage::getState(lnk, state, x, y); } @@ -7010,8 +7064,8 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i QString HistoryReply::selectedText(uint32 selection) const { if (selection != FullSelection || !replyToMsg) return HistoryMessage::selectedText(selection); QString result, original = HistoryMessage::selectedText(selection); - result.reserve(lang(lng_in_reply_to).size() + replyToMsg->from()->name.size() + 4 + original.size()); - result.append('[').append(lang(lng_in_reply_to)).append(' ').append(replyToMsg->from()->name).append(qsl("]\n")).append(original); + result.reserve(lang(lng_in_reply_to).size() + replyToMsg->author()->name.size() + 4 + original.size()); + result.append('[').append(lang(lng_in_reply_to)).append(' ').append(replyToMsg->author()->name).append(qsl("]\n")).append(original); return result; } @@ -7040,7 +7094,8 @@ bool HistoryReply::updateReplyTo(bool force) { replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id)); if (!replyToMsg->toHistoryForwarded()) { if (UserData *bot = replyToMsg->viaBot()) { - _replyToVia = new HistoryMessageVia(peerToUser(bot->id)); + _replyToVia = new HistoryMessageVia(0); + _replyToVia->create(peerToUser(bot->id)); } } } else if (force) { @@ -7055,9 +7110,9 @@ bool HistoryReply::updateReplyTo(bool force) { void HistoryReply::replyToNameUpdated() const { if (replyToMsg) { - QString name = (replyToVia() && replyToMsg->from()->isUser()) ? replyToMsg->from()->asUser()->firstName : App::peerName(replyToMsg->from()); + QString name = (replyToVia() && replyToMsg->author()->isUser()) ? replyToMsg->author()->asUser()->firstName : App::peerName(replyToMsg->author()); replyToName.setText(st::msgServiceNameFont, name, _textNameOptions); - replyToVersion = replyToMsg->from()->nameVersion; + replyToVersion = replyToMsg->author()->nameVersion; bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; int32 w = replyToName.maxWidth(); @@ -7098,14 +7153,15 @@ void HistoryReply::replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem) { initDimensions(); } else if (!replyToMsg->toHistoryForwarded()) { if (UserData *bot = replyToMsg->viaBot()) { - _replyToVia = new HistoryMessageVia(peerToUser(bot->id)); + _replyToVia = new HistoryMessageVia(0); + _replyToVia->create(peerToUser(bot->id)); } } } } void HistoryReply::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const { - if (replyToMsg && replyToMsg->from()->nameVersion > replyToVersion) { + if (replyToMsg && replyToMsg->author()->nameVersion > replyToVersion) { replyToNameUpdated(); } HistoryMessage::draw(p, r, selection, ms); @@ -7113,7 +7169,7 @@ void HistoryReply::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) void HistoryReply::drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService) const { style::color bar; - bool outbg = out() && !fromChannel(); + bool outbg = out() && !isPost(); if (likeService) { bar = st::white; } else { @@ -7223,7 +7279,7 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x int32 left = 0, width = 0; countPositionAndSize(left, width); if (displayFromPhoto()) { - int32 photoleft = left + ((!fromChannel() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); + int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); if (x >= photoleft && x < photoleft + st::msgPhotoSize) { return HistoryMessage::getState(lnk, state, x, y); } @@ -7372,7 +7428,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionChannelCreate: { const MTPDmessageActionChannelCreate &d(action.c_messageActionChannelCreate()); - if (fromChannel()) { + if (isPost()) { text = lng_action_created_channel(lt_title, textClean(qs(d.vtitle))); } else { text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle))); @@ -7380,7 +7436,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { } break; case mtpc_messageActionChatDeletePhoto: { - text = fromChannel() ? lang(lng_action_removed_photo_channel) : lng_action_removed_photo(lt_from, from); + text = isPost() ? lang(lng_action_removed_photo_channel) : lng_action_removed_photo(lt_from, from); } break; case mtpc_messageActionChatDeleteUser: { @@ -7399,12 +7455,12 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { if (d.vphoto.type() == mtpc_photo) { _media = new HistoryPhoto(history()->peer, d.vphoto.c_photo(), st::msgServicePhotoWidth); } - text = fromChannel() ? lang(lng_action_changed_photo_channel) : lng_action_changed_photo(lt_from, from); + text = isPost() ? lang(lng_action_changed_photo_channel) : lng_action_changed_photo(lt_from, from); } break; case mtpc_messageActionChatEditTitle: { const MTPDmessageActionChatEditTitle &d(action.c_messageActionChatEditTitle()); - text = fromChannel() ? lng_action_changed_title_channel(lt_title, textClean(qs(d.vtitle))) : lng_action_changed_title(lt_from, from, lt_title, textClean(qs(d.vtitle))); + text = isPost() ? lng_action_changed_title_channel(lt_title, textClean(qs(d.vtitle))) : lng_action_changed_title(lt_from, from, lt_title, textClean(qs(d.vtitle))); } break; case mtpc_messageActionChatMigrateTo: { @@ -7483,7 +7539,7 @@ QString HistoryServiceMsg::inDialogsText() const { QString HistoryServiceMsg::inReplyText() const { QString result = HistoryServiceMsg::inDialogsText(); - return result.trimmed().startsWith(from()->name) ? result.trimmed().mid(from()->name.size()).trimmed() : result; + return result.trimmed().startsWith(author()->name) ? result.trimmed().mid(author()->name.size()).trimmed() : result; } void HistoryServiceMsg::setServiceText(const QString &text) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 0ac06d6140..c5f667f253 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -189,14 +189,14 @@ public: } HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction); - HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg); + HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg); HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryItem *createItemPhoto(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); HistoryItem *addToHistory(const MTPMessage &msg); - HistoryItem *addNewForwarded(MsgId id, QDateTime date, int32 from, HistoryMessage *item); + HistoryItem *addNewForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *item); HistoryItem *addNewDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryItem *addNewPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); @@ -779,7 +779,7 @@ enum InfoDisplayType { }; inline bool isImportantChannelMessage(MsgId id, int32 flags) { // client-side important msgs always has_views or has_from_id - return (flags & MTPDmessage::flag_out) || (flags & MTPDmessage::flag_mentioned) || ((id > 0 || flags != 0) && !(flags & MTPDmessage::flag_from_id)); + return (flags & MTPDmessage::flag_out) || (flags & MTPDmessage::flag_mentioned) || (flags & MTPDmessage::flag_post); } enum HistoryItemType { @@ -860,14 +860,20 @@ public: bool hasViews() const { return _flags & MTPDmessage::flag_views; } - bool fromChannel() const { - return _from->isChannel(); + bool isPost() const { + return _flags & MTPDmessage::flag_post; } bool isImportant() const { return _history->isChannel() && isImportantChannelMessage(id, _flags); } bool indexInOverview() const { - return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || fromChannel()); + return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || isPost()); + } + bool isSilent() const { + return _flags & MTPDmessage::flag_silent; + } + virtual int32 viewsCount() const { + return hasViews() ? 1 : -1; } virtual bool needCheck() const { @@ -937,7 +943,7 @@ public: if (id == 1) return false; if (channel->amCreator()) return true; - if (fromChannel()) { + if (isPost()) { if (channel->amEditor() && out()) return true; return false; } @@ -979,12 +985,6 @@ public: virtual int32 timeWidth() const { return 0; } - virtual QString viewsText() const { - return QString(); - } - virtual int32 viewsWidth() const { - return 0; - } virtual bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const { return false; } @@ -1019,7 +1019,10 @@ public: } bool hasFromName() const { - return (!out() || fromChannel()) && !history()->peer->isUser(); + return (!out() || isPost()) && !history()->peer->isUser(); + } + PeerData *author() const { + return isPost() ? history()->peer : _from; } bool displayFromPhoto() const; @@ -1030,11 +1033,12 @@ public: protected: PeerData *_from; - mutable int32 _fromVersion; History *_history; HistoryBlock *_block; int32 _flags; + mutable int32 _authorNameVersion; + }; class MessageLink : public ITextLink { @@ -1931,25 +1935,40 @@ private: }; -class HistoryMessageVia { -public: - HistoryMessageVia(int32 userId); +struct HistoryMessageVia : public BasicInterface { + HistoryMessageVia(Interfaces *); + + void create(int32 userId); bool isNull() const; - void resize(int32 availw); + void resize(int32 availw) const; UserData *bot; - QString text; - int32 width, maxWidth; + mutable QString text; + mutable int32 width, maxWidth; TextLinkPtr lnk; - }; -class HistoryMessage : public HistoryItem { +struct HistoryMessageViews : public BasicInterface { + HistoryMessageViews(Interfaces *); + + QString _viewsText; + int32 _views, _viewsWidth; +}; + +struct HistoryMessageSigned : public BasicInterface { + HistoryMessageSigned(Interfaces *); + void create(UserData *from, const QDateTime &date); + int32 maxWidth() const; + + Text _signature; +}; + +class HistoryMessage : public HistoryItem, public Interfaces { public: HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg); - HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities, HistoryMedia *media); // local forwarded + HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities, int32 fromViews, HistoryMedia *fromMedia); // local forwarded HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo @@ -1959,8 +1978,9 @@ public: void initDimensions(); void fromNameUpdated(int32 width) const; - virtual HistoryMessageVia *via() const { - return (_via && !_via->isNull()) ? _via : 0; + const HistoryMessageVia *via() const { + const HistoryMessageVia *result = Get(); + return (result && !result->isNull()) ? result : 0; } virtual UserData *viaBot() const { return via() ? via()->bot : 0; @@ -2037,20 +2057,20 @@ public: int32 infoWidth() const { int32 result = _timeWidth; - if (!_viewsText.isEmpty()) { - result += st::msgDateViewsSpace + _viewsWidth + st::msgDateCheckSpace + st::msgViewsImg.pxWidth(); + if (const HistoryMessageViews *views = Get()) { + result += st::msgDateViewsSpace + views->_viewsWidth + st::msgDateCheckSpace + st::msgViewsImg.pxWidth(); } else if (id < 0 && history()->peer->isSelf()) { result += st::msgDateCheckSpace + st::msgCheckImg.pxWidth(); } - if (out() && !fromChannel()) { + if (out() && !isPost()) { result += st::msgDateCheckSpace + st::msgCheckImg.pxWidth(); } return result; } int32 timeLeft() const { int32 result = 0; - if (!_viewsText.isEmpty()) { - result += st::msgDateViewsSpace + _viewsWidth + st::msgDateCheckSpace + st::msgViewsImg.pxWidth(); + if (const HistoryMessageViews *views = Get()) { + result += st::msgDateViewsSpace + views->_viewsWidth + st::msgDateCheckSpace + st::msgViewsImg.pxWidth(); } else if (id < 0 && history()->peer->isSelf()) { result += st::msgDateCheckSpace + st::msgCheckImg.pxWidth(); } @@ -2059,18 +2079,19 @@ public: int32 timeWidth() const { return _timeWidth; } - QString viewsText() const { - return _viewsText; - } - int32 viewsWidth() const { - return _viewsWidth; + + int32 viewsCount() const { + if (const HistoryMessageViews *views = Get()) { + return views->_views; + } + return HistoryItem::viewsCount(); } virtual QDateTime dateForwarded() const { // dynamic_cast optimize return date; } virtual PeerData *fromForwarded() const { // dynamic_cast optimize - return from(); + return author(); } HistoryMessage *toHistoryMessage() { // dynamic_cast optimize @@ -2084,25 +2105,23 @@ public: protected: + void create(int32 viaBotId, int32 viewsCount); + Text _text; int32 _textWidth, _textHeight; - HistoryMessageVia *_via; HistoryMedia *_media; QString _timeText; int32 _timeWidth; - QString _viewsText; - int32 _views, _viewsWidth; - }; class HistoryForwarded : public HistoryMessage { public: HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg); - HistoryForwarded(History *history, HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg); + HistoryForwarded(History *history, HistoryBlock *block, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg); void initDimensions(); void fwdNameUpdated() const; @@ -2175,7 +2194,7 @@ public: void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; PeerData *replyTo() const { - return replyToMsg ? replyToMsg->from() : 0; + return replyToMsg ? replyToMsg->author() : 0; } QString selectedText(uint32 selection) const; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index a7e5a35958..d197e54593 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -844,10 +844,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } else { uint16 symbol, selFrom = (_selected.cbegin().value() >> 16) & 0xFFFF, selTo = _selected.cbegin().value() & 0xFFFF; hasSelected = (selTo > selFrom) ? 1 : 0; - if (_dragItem && _dragItem == App::hoveredItem()) { - QPoint mousePos(mapMouseToItem(mapFromGlobal(_dragPos), _dragItem)); + if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) { + QPoint mousePos(mapMouseToItem(mapFromGlobal(_dragPos), App::mousedItem())); bool afterDragSymbol, uponSymbol; - _dragItem->getSymbol(symbol, afterDragSymbol, uponSymbol, mousePos.x(), mousePos.y()); + App::mousedItem()->getSymbol(symbol, afterDragSymbol, uponSymbol, mousePos.x(), mousePos.y()); if (uponSymbol && symbol >= selFrom && symbol < selTo) { isUponSelected = 1; } @@ -963,16 +963,17 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } - if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + QLatin1String linktype = _contextMenuLnk ? _contextMenuLnk->type() : qstr(""); + if (linktype == qstr("TextLink") || linktype == qstr("LocationLink")) { _menu->addAction(lang(lng_context_open_link), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_link), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + } else if (linktype == qstr("EmailLink")) { _menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + } else if (linktype == qstr("MentionLink")) { _menu->addAction(lang(lng_context_open_mention), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + } else if (linktype == qstr("HashtagLink")) { _menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_hashtag), this, SLOT(copyContextUrl()))->setEnabled(true); } else { @@ -1159,12 +1160,12 @@ QString HistoryInner::getSelectedText() const { if (item->detached()) continue; QString text, sel = item->selectedText(FullSelection), time = item->date.toString(timeFormat); - int32 size = item->from()->name.size() + time.size() + sel.size(); + int32 size = item->author()->name.size() + time.size() + sel.size(); text.reserve(size); int32 y = itemTop(item); if (y >= 0) { - texts.insert(y, text.append(item->from()->name).append(time).append(sel)); + texts.insert(y, text.append(item->author()->name).append(time).append(sel)); fullSize += size; } } @@ -3474,7 +3475,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re _canSendMessages = canSendMessages(_peer); if (_peer && _peer->isChannel()) { _peer->asChannel()->updateFull(); - _joinChannel.setText(lang(lng_channel_join)); + _joinChannel.setText(lang(_peer->isMegagroup() ? lng_group_invite_join : lng_channel_join)); } _unblockRequest = _reportSpamRequest = 0; @@ -4553,14 +4554,17 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } - bool fromChannelName = p->isChannel() && !p->isMegagroup() && p->asChannel()->canPublish() && (p->asChannel()->isBroadcast() || _broadcast.checked()); - if (fromChannelName) { + bool channelPost = p->isChannel() && !p->isMegagroup() && p->asChannel()->canPublish() && (p->asChannel()->isBroadcast() || _broadcast.checked()); + bool showFromName = !channelPost || p->asChannel()->addsSignature(); + if (channelPost) { sendFlags |= MTPmessages_SendMedia::flag_broadcast; flags |= MTPDmessage::flag_views; - } else { + flags |= MTPDmessage::flag_post; + } + if (showFromName) { flags |= MTPDmessage::flag_from_id; } - h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(peer), MTPPeer(), 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, MTP_int(1)), NewMessageUnread); + h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(peer), MTPPeer(), MTPint(), 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, MTP_int(1)), NewMessageUnread); 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); @@ -5518,21 +5522,24 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out if (file->to.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id; - bool fromChannelName = h->peer->isChannel() && !h->peer->isMegagroup() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || file->to.broadcast); - if (fromChannelName) { + bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || file->to.broadcast); + bool showFromName = !channelPost || h->peer->asChannel()->addsSignature(); + if (channelPost) { flags |= MTPDmessage::flag_views; - } else { + flags |= MTPDmessage::flag_post; + } + if (showFromName) { flags |= MTPDmessage::flag_from_id; } if (file->type == PreparePhoto) { - h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(file->photo, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); + h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(file->photo, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); } else if (file->type == PrepareDocument) { - h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); + h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); } else if (file->type == PrepareAudio) { if (!h->peer->isChannel()) { flags |= MTPDmessage::flag_media_unread; } - h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); + h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); } if (_peer && file->to.peer == _peer->id) { @@ -5583,8 +5590,8 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, const MTPInputFile & sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } - bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->fromChannel(); - if (fromChannelName) { + bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); + if (channelPost) { sendFlags |= MTPmessages_SendMedia::flag_broadcast; } QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); @@ -5631,8 +5638,8 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, const MTPInputFil sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } - bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->fromChannel(); - if (fromChannelName) { + bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); + if (channelPost) { sendFlags |= MTPmessages_SendMedia::flag_broadcast; } QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); @@ -5656,8 +5663,8 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, const MTPInp sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } - bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->fromChannel(); - if (fromChannelName) { + bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); + if (channelPost) { sendFlags |= MTPmessages_SendMedia::flag_broadcast; } QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); @@ -5670,7 +5677,7 @@ void HistoryWidget::onPhotoProgress(const FullMsgId &newId) { if (!MTP::authedId()) return; if (HistoryItem *item = App::histItemById(newId)) { PhotoData *photo = (item->getMedia() && item->getMedia()->type() == MediaTypePhoto) ? static_cast(item->getMedia())->photo() : 0; - if (!item->fromChannel()) { + if (!item->isPost()) { updateSendAction(item->history(), SendActionUploadPhoto, 0); } Ui::repaintHistoryItem(item); @@ -5682,7 +5689,7 @@ void HistoryWidget::onDocumentProgress(const FullMsgId &newId) { if (HistoryItem *item = App::histItemById(newId)) { HistoryMedia *media = item->getMedia(); DocumentData *doc = media ? media->getDocument() : 0; - if (!item->fromChannel()) { + if (!item->isPost()) { updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, doc ? doc->uploadOffset : 0); } Ui::repaintHistoryItem(item); @@ -5693,7 +5700,7 @@ void HistoryWidget::onPhotoFailed(const FullMsgId &newId) { if (!MTP::authedId()) return; HistoryItem *item = App::histItemById(newId); if (item) { - if (!item->fromChannel()) { + if (!item->isPost()) { updateSendAction(item->history(), SendActionUploadPhoto, -1); } // Ui::repaintHistoryItem(item); @@ -5706,7 +5713,7 @@ void HistoryWidget::onDocumentFailed(const FullMsgId &newId) { if (item) { HistoryMedia *media = item->getMedia(); DocumentData *doc = media ? media->getDocument() : 0; - if (!item->fromChannel()) { + if (!item->isPost()) { updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, -1); } Ui::repaintHistoryItem(item); @@ -6355,10 +6362,14 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { flags |= MTPDmessage::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; } - bool fromChannelName = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked()); - if (fromChannelName) { + bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked()); + bool showFromName = !channelPost || _peer->asChannel()->addsSignature(); + if (channelPost) { sendFlags |= MTPmessages_SendMedia::flag_broadcast; - } else { + flags |= MTPDmessage::flag_views; + flags |= MTPDmessage::flag_post; + } + if (showFromName) { flags |= MTPDmessage::flag_from_id; } if (bot) { @@ -6367,9 +6378,9 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { if (result->message.isEmpty()) { if (result->doc) { - _history->addNewDocument(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), result->doc, result->caption); + _history->addNewDocument(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, result->doc, result->caption); } else if (result->photo) { - _history->addNewPhoto(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), result->photo, result->caption); + _history->addNewPhoto(newId.msg, flags, bot ? peerToUser(bot->id) : 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, result->photo, result->caption); } else if (result->type == qstr("gif")) { MTPPhotoSize thumbSize; QPixmap thumb; @@ -6399,7 +6410,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { App::feedDocument(document, thumb); } Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), result->data()); - _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(document, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); + _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(document, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); } else if (result->type == qstr("photo")) { QImage fileThumb(result->thumb->pix().toImage()); @@ -6418,14 +6429,14 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) { PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(result->width, result->height)); MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector(photoSizes)); - _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); + _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread); } } else { flags |= MTPDmessage::flag_entities; if (result->noWebPage) { sendFlags |= MTPmessages_SendMessage::flag_no_webpage; } - _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(result->message), MTP_messageMediaEmpty(), MTPnullMarkup, linksToMTP(result->entities), MTP_int(1)), NewMessageUnread); + _history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(result->message), MTP_messageMediaEmpty(), MTPnullMarkup, linksToMTP(result->entities), MTP_int(1)), NewMessageUnread); } _history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->queryId), MTP_string(result->id)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); App::main()->finishForwarding(_history, _broadcast.checked()); @@ -7016,8 +7027,8 @@ void HistoryWidget::updateForwarding(bool force) { void HistoryWidget::updateReplyToName() { if (!_replyTo && (_replyToId || !_kbReplyTo)) return; - _replyToName.setText(st::msgServiceNameFont, App::peerName((_replyTo ? _replyTo : _kbReplyTo)->from()), _textNameOptions); - _replyToNameVersion = (_replyTo ? _replyTo : _kbReplyTo)->from()->nameVersion; + _replyToName.setText(st::msgServiceNameFont, App::peerName((_replyTo ? _replyTo : _kbReplyTo)->author()), _textNameOptions); + _replyToNameVersion = (_replyTo ? _replyTo : _kbReplyTo)->author()->nameVersion; } void HistoryWidget::updateField() { @@ -7032,7 +7043,7 @@ void HistoryWidget::drawField(Painter &p) { ImagePtr preview; HistoryItem *drawReplyTo = _replyToId ? _replyTo : _kbReplyTo; if (_replyToId || (!hasForward && _kbReplyTo)) { - if (drawReplyTo && drawReplyTo->from()->nameVersion > _replyToNameVersion) { + if (drawReplyTo && drawReplyTo->author()->nameVersion > _replyToNameVersion) { updateReplyToName(); } backy -= st::replyHeight; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 8944d59f38..181fd9b840 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -395,7 +395,6 @@ MainWidget::MainWidget(Window *window) : TWidget(window) , _hider(0) , _peerInStack(0) , _msgIdInStack(0) -, _stickerPreview(0) , _playerHeight(0) , _contentScrollAddToY(0) , _mediaType(this) @@ -541,7 +540,7 @@ void MainWidget::fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor if (HistoryForwarded *fwd = i.value()->toHistoryForwarded()) { version += fwd->fromForwarded()->nameVersion; } else { - version += i.value()->from()->nameVersion; + version += i.value()->author()->nameVersion; } } if (version != _toForwardNameVersion) { @@ -563,7 +562,7 @@ void MainWidget::updateForwardingTexts() { QVector fromUsers; fromUsers.reserve(_toForward.size()); for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { - PeerData *from = i.value()->from(); + PeerData *from = i.value()->author(); if (HistoryForwarded *fwd = i.value()->toHistoryForwarded()) { from = fwd->fromForwarded(); } @@ -571,7 +570,7 @@ void MainWidget::updateForwardingTexts() { fromUsersMap.insert(from, true); fromUsers.push_back(from); } - version += i.value()->from()->nameVersion; + version += from->nameVersion; } if (fromUsers.size() > 2) { from = lng_forwarding_from(lt_user, fromUsers.at(0)->shortName(), lt_count, fromUsers.size() - 1); @@ -602,13 +601,22 @@ void MainWidget::cancelForwarding() { void MainWidget::finishForwarding(History *hist, bool broadcast) { if (!hist) return; - bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); if (!_toForward.isEmpty()) { bool genClientSideMessage = (_toForward.size() < 2); PeerData *forwardFrom = 0; App::main()->readServerHistory(hist, false); - int32 flags = fromChannelName ? MTPmessages_ForwardMessages::flag_broadcast : 0; + int32 sendFlags = 0, flags = 0; + bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); + bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature(); + if (channelPost) { + sendFlags |= MTPmessages_ForwardMessages::flag_broadcast; + flags |= MTPDmessage::flag_views; + flags |= MTPDmessage::flag_post; + } + if (showFromName) { + flags |= MTPDmessage::flag_from_id; + } QVector ids; QVector randomIds; @@ -619,7 +627,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast) { if (genClientSideMessage) { FullMsgId newId(peerToChannel(hist->peer->id), clientMsgId()); HistoryMessage *msg = static_cast(_toForward.cbegin().value()); - hist->addNewForwarded(newId.msg, date(MTP_int(unixtime())), fromChannelName ? 0 : MTP::authedId(), msg); + hist->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, msg); if (HistoryMedia *media = msg->getMedia()) { if (media->type() == MediaTypeSticker) { App::main()->incrementSticker(media->getDocument()); @@ -629,7 +637,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast) { } if (forwardFrom != i.value()->history()->peer) { if (forwardFrom) { - hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(flags), forwardFrom->input, MTP_vector(ids), MTP_vector(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(sendFlags), forwardFrom->input, MTP_vector(ids), MTP_vector(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); ids.resize(0); randomIds.resize(0); } @@ -638,7 +646,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast) { ids.push_back(MTP_int(i.value()->id)); randomIds.push_back(MTP_long(randomId)); } - hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(flags), forwardFrom->input, MTP_vector(ids), MTP_vector(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); + hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(sendFlags), forwardFrom->input, MTP_vector(ids), MTP_vector(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); if (history.peer() == hist->peer) { history.peerMessagesUpdated(); @@ -741,20 +749,6 @@ QPixmap MainWidget::grabTopBar() { } } -void MainWidget::ui_showStickerPreview(DocumentData *sticker) { - if (!sticker || ((!sticker->isAnimation() || !sticker->loaded()) && !sticker->sticker())) return; - if (!_stickerPreview) { - _stickerPreview = new StickerPreviewWidget(this); - resizeEvent(0); - } - _stickerPreview->showPreview(sticker); -} - -void MainWidget::ui_hideStickerPreview() { - if (!_stickerPreview) return; - _stickerPreview->hidePreview(); -} - void MainWidget::notify_botCommandsChanged(UserData *bot) { history.notify_botCommandsChanged(bot); } @@ -1320,18 +1314,21 @@ void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo, media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill))); flags |= MTPDmessage::flag_media; } - bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); - if (fromChannelName) { + bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); + bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature(); + if (channelPost) { sendFlags |= MTPmessages_SendMessage::flag_broadcast; flags |= MTPDmessage::flag_views; - } else { + flags |= MTPDmessage::flag_post; + } + if (showFromName) { flags |= MTPDmessage::flag_from_id; } MTPVector localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true); if (!sentEntities.c_vector().v.isEmpty()) { sendFlags |= MTPmessages_SendMessage::flag_entities; } - hist->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(hist->peer->id), MTPPeer(), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities, MTP_int(1)), NewMessageUnread); + hist->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(hist->peer->id), MTPPeer(), MTPint(), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities, MTP_int(1)), NewMessageUnread); hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, sentEntities), rpcDone(&MainWidget::sentUpdatesReceived, randomId), rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); } @@ -1915,7 +1912,7 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia & HistoryItem *item = 0; while (textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) { MTPVector localEntities = linksToMTP(sendingEntities); - item = App::histories().addNewMessage(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPPeer(), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint()), NewMessageUnread); + item = App::histories().addNewMessage(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPPeer(), MTPint(), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint()), NewMessageUnread); } if (item) { history.peerMessagesUpdated(item->history()->peer->id); @@ -2502,7 +2499,6 @@ void MainWidget::orderWidgets() { dialogs.raise(); _mediaType.raise(); if (_hider) _hider->raise(); - if (_stickerPreview) _stickerPreview->raise(); } QRect MainWidget::historyRect() const { @@ -2751,7 +2747,6 @@ void MainWidget::resizeEvent(QResizeEvent *e) { _mediaType.moveToLeft(width() - _mediaType.width(), _playerHeight + st::topBarHeight); if (profile) profile->setGeometry(history.geometry()); if (overview) overview->setGeometry(history.geometry()); - if (_stickerPreview) _stickerPreview->setGeometry(rect()); _contentScrollAddToY = 0; } @@ -3405,10 +3400,24 @@ bool MainWidget::started() { void MainWidget::openLocalUrl(const QString &url) { QString u(url.trimmed()); if (u.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) { - QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+))?(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u); + QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u); if (m.hasMatch()) { - QString start = m.captured(3), startToken = m.captured(4); - openPeerByName(m.captured(1), (start == qsl("startgroup")), startToken); + QString params = u.mid(m.capturedLength(0)); + + QString start, startToken; + QRegularExpressionMatch startparam = QRegularExpression(qsl("(^|&)(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+)(&|$)")).match(params); + if (startparam.hasMatch()) { + start = startparam.captured(2); + startToken = startparam.captured(3); + } + + MsgId post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId; + QRegularExpressionMatch postparam = QRegularExpression(qsl("(^|&)post=(\\d+)(&|$)")).match(params); + if (postparam.hasMatch()) { + post = postparam.captured(2).toInt(); + } + + openPeerByName(m.captured(1), post, startToken); } } else if (u.startsWith(qstr("tg://join"), Qt::CaseInsensitive)) { QRegularExpressionMatch m = QRegularExpression(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u); @@ -3439,12 +3448,12 @@ void MainWidget::openLocalUrl(const QString &url) { } } -void MainWidget::openPeerByName(const QString &username, bool toProfile, const QString &startToken) { +void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QString &startToken) { App::wnd()->hideMediaview(); PeerData *peer = App::peerByName(username); if (peer) { - if (toProfile && !peer->isChannel()) { + if (msgId == ShowAtProfileMsgId && !peer->isChannel()) { if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) { peer->asUser()->botInfo->startGroupToken = startToken; Ui::showLayer(new ContactsBox(peer->asUser())); @@ -3452,6 +3461,9 @@ void MainWidget::openPeerByName(const QString &username, bool toProfile, const Q showPeerProfile(peer); } } else { + if (msgId == ShowAtProfileMsgId) { + msgId = ShowAtUnreadMsgId; + } if (peer->isUser() && peer->asUser()->botInfo) { peer->asUser()->botInfo->startToken = startToken; if (peer == history.peer()) { @@ -3459,10 +3471,10 @@ void MainWidget::openPeerByName(const QString &username, bool toProfile, const Q history.resizeEvent(0); } } - Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId); + Ui::showPeerHistoryAsync(peer->id, msgId); } } else { - MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, qMakePair(toProfile, startToken)), rpcFail(&MainWidget::usernameResolveFail, username)); + MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, qMakePair(msgId, startToken)), rpcFail(&MainWidget::usernameResolveFail, username)); } } @@ -3508,7 +3520,7 @@ bool MainWidget::contentOverlapped(const QRect &globalRect) { _mediaType.overlaps(globalRect)); } -void MainWidget::usernameResolveDone(QPair toProfileStartToken, const MTPcontacts_ResolvedPeer &result) { +void MainWidget::usernameResolveDone(QPair msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result) { Ui::hideLayer(); if (result.type() != mtpc_contacts_resolvedPeer) return; @@ -3519,24 +3531,27 @@ void MainWidget::usernameResolveDone(QPair toProfileStartToken, c if (!peerId) return; PeerData *peer = App::peer(peerId); - if (toProfileStartToken.first) { - if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !toProfileStartToken.second.isEmpty()) { - peer->asUser()->botInfo->startGroupToken = toProfileStartToken.second; + MsgId msgId = msgIdAndStartToken.first; + QString startToken = msgIdAndStartToken.second; + if (msgId == ShowAtProfileMsgId && !peer->isChannel()) { + if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) { + peer->asUser()->botInfo->startGroupToken = startToken; Ui::showLayer(new ContactsBox(peer->asUser())); - } else if (peer->isChannel()) { - Ui::showPeerHistory(peer->id, ShowAtUnreadMsgId); } else { showPeerProfile(peer); } } else { + if (msgId == ShowAtProfileMsgId) { + msgId = ShowAtUnreadMsgId; + } if (peer->isUser() && peer->asUser()->botInfo) { - peer->asUser()->botInfo->startToken = toProfileStartToken.second; + peer->asUser()->botInfo->startToken = startToken; if (peer == history.peer()) { history.updateControlsVisibility(); history.resizeEvent(0); } } - Ui::showPeerHistory(peer->id, ShowAtUnreadMsgId); + Ui::showPeerHistory(peer->id, msgId); } } @@ -4007,7 +4022,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { // update before applying skipped int32 flags = d.vflags.v | MTPDmessage::flag_from_id; - HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.is_out() ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint()), NewMessageUnread); + HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.is_out() ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vfwd_post, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint()), NewMessageUnread); if (item) { history.peerMessagesUpdated(item->history()->peer->id); } @@ -4032,7 +4047,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { // update before applying skipped int32 flags = d.vflags.v | MTPDmessage::flag_from_id; - HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint()), NewMessageUnread); + HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vfwd_post, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint()), NewMessageUnread); if (item) { history.peerMessagesUpdated(item->history()->peer->id); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 31a8989df8..075a37474d 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -183,8 +183,6 @@ inline int chatsListWidth(int windowWidth) { return snap((windowWidth * 5) / 14, st::dlgMinWidth, st::dlgMaxWidth); } -class StickerPreviewWidget; - class MainWidget : public TWidget, public RPCSender { Q_OBJECT @@ -212,7 +210,7 @@ public: void start(const MTPUser &user); void openLocalUrl(const QString &str); - void openPeerByName(const QString &name, bool toProfile = false, const QString &startToken = QString()); + void openPeerByName(const QString &name, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString()); void joinGroupByHash(const QString &hash); void stickersBox(const MTPInputStickerSet &set); @@ -410,8 +408,6 @@ public: bool isItemVisible(HistoryItem *item); - void ui_showStickerPreview(DocumentData *sticker); - void ui_hideStickerPreview(); void ui_repaintHistoryItem(const HistoryItem *item); void ui_repaintInlineItem(const LayoutInlineItem *layout); bool ui_isInlineItemVisible(const LayoutInlineItem *layout); @@ -544,7 +540,7 @@ private: void updateReceived(const mtpPrime *from, const mtpPrime *end); bool updateFail(const RPCError &e); - void usernameResolveDone(QPair toProfileStartToken, const MTPcontacts_ResolvedPeer &result); + void usernameResolveDone(QPair msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result); bool usernameResolveFail(QString name, const RPCError &error); void inviteCheckDone(QString hash, const MTPChatInvite &invite); @@ -578,8 +574,6 @@ private: PeerData *_peerInStack; MsgId _msgIdInStack; - StickerPreviewWidget *_stickerPreview; - int32 _playerHeight; int32 _contentScrollAddToY; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index a73603e016..c8719fb3f0 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -883,7 +883,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { _caption = Text(); if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : 0) { if (HistoryPhoto *photoMsg = dynamic_cast(itemMsg->getMedia())) { - _caption.setText(st::mvCaptionFont, photoMsg->getCaption(), (item->from()->isUser() && item->from()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions); + _caption.setText(st::mvCaptionFont, photoMsg->getCaption(), (item->author()->isUser() && item->author()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions); } } @@ -912,7 +912,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { if (HistoryForwarded *fwd = item->toHistoryForwarded()) { _from = fwd->fromForwarded(); } else { - _from = item->from(); + _from = item->author(); } } else { _from = _user; @@ -1065,7 +1065,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty if (HistoryForwarded *fwd = item->toHistoryForwarded()) { _from = fwd->fromForwarded(); } else { - _from = item->from(); + _from = item->author(); } _full = 1; updateControls(); diff --git a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h index b6dab0b004..b1f655dc49 100644 --- a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h +++ b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h @@ -368,7 +368,7 @@ static const mtpTypeId mtpLayers[] = { mtpTypeId(mtpc_invokeWithLayer18), }; static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]); -static const mtpPrime mtpCurrentLayer = 47; +static const mtpPrime mtpCurrentLayer = 48; template class MTPBoxed : public bareT { diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp index e2231a54ae..462d46aeaf 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp +++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp @@ -1154,15 +1154,16 @@ void _serialize_channel(MTPStringLogger &to, int32 stage, int32 lev, Types &type case 7: to.add(" verified: "); ++stages.back(); if (flag & MTPDchannel::flag_verified) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break; case 8: to.add(" megagroup: "); ++stages.back(); if (flag & MTPDchannel::flag_megagroup) { to.add("YES [ BY BIT 8 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break; case 9: to.add(" restricted: "); ++stages.back(); if (flag & MTPDchannel::flag_restricted) { to.add("YES [ BY BIT 9 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break; - case 10: to.add(" invites_enabled: "); ++stages.back(); if (flag & MTPDchannel::flag_invites_enabled) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break; - case 11: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 12: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 13: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 14: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break; - case 15: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 16: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 17: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 18: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); 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(" admin_invites: "); ++stages.back(); if (flag & MTPDchannel::flag_admin_invites) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break; + case 11: to.add(" signatures: "); ++stages.back(); if (flag & MTPDchannel::flag_signatures) { to.add("YES [ BY BIT 11 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; + case 12: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 13: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 14: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 15: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break; + case 16: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 17: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 18: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 19: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -1345,19 +1346,22 @@ void _serialize_message(MTPStringLogger &to, int32 stage, int32 lev, Types &type case 2: to.add(" out: "); ++stages.back(); if (flag & MTPDmessage::flag_out) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; case 3: to.add(" mentioned: "); ++stages.back(); if (flag & MTPDmessage::flag_mentioned) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; case 4: to.add(" media_unread: "); ++stages.back(); if (flag & MTPDmessage::flag_media_unread) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; - case 5: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: 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 7: to.add(" to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 8: 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 9: 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 10: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDmessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; - case 11: 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 12: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 13: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 14: 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 15: 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 16: 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 17: 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; + case 5: to.add(" silent: "); ++stages.back(); if (flag & MTPDmessage::flag_silent) { to.add("YES [ BY BIT 13 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 13 IN FIELD flags ]"); } break; + case 6: to.add(" post: "); ++stages.back(); if (flag & MTPDmessage::flag_post) { to.add("YES [ BY BIT 14 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 14 IN FIELD flags ]"); } break; + case 7: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 8: 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 9: to.add(" to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 10: 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 11: 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 12: to.add(" fwd_post: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_post) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 12 IN FIELD flags ]"); } break; + case 13: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDmessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; + case 14: 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 15: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 16: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 17: 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 18: 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 19: 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 20: 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; } } @@ -2952,17 +2956,19 @@ void _serialize_updateShortMessage(MTPStringLogger &to, int32 stage, int32 lev, case 2: to.add(" out: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_out) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; case 3: to.add(" mentioned: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_mentioned) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; case 4: to.add(" media_unread: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_media_unread) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; - case 5: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: 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 7: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 8: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 9: 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 10: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 11: 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 12: 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 13: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; - case 14: 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 15: 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; + case 5: to.add(" silent: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_silent) { to.add("YES [ BY BIT 13 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 13 IN FIELD flags ]"); } break; + case 6: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: 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 8: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 9: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 10: 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 11: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 12: 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 13: 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 14: to.add(" fwd_post: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_post) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 12 IN FIELD flags ]"); } break; + case 15: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; + case 16: 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 17: 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; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -2980,18 +2986,20 @@ void _serialize_updateShortChatMessage(MTPStringLogger &to, int32 stage, int32 l case 2: to.add(" out: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_out) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; case 3: to.add(" mentioned: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_mentioned) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; case 4: to.add(" media_unread: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_media_unread) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; - case 5: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 7: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 8: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 9: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 10: 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 11: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 12: 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 13: 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 14: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; - case 15: 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 16: 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; + case 5: to.add(" silent: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_silent) { to.add("YES [ BY BIT 13 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 13 IN FIELD flags ]"); } break; + case 6: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 8: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 9: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 10: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 11: 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 12: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 13: 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 14: 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 15: to.add(" fwd_post: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_post) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 12 IN FIELD flags ]"); } break; + case 16: to.add(" via_bot_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_via_bot_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break; + case 17: 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 18: 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; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -3135,9 +3143,10 @@ void _serialize_dcOption(MTPStringLogger &to, int32 stage, int32 lev, Types &typ 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(" ipv6: "); ++stages.back(); if (flag & MTPDdcOption::flag_ipv6) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; case 2: to.add(" media_only: "); ++stages.back(); if (flag & MTPDdcOption::flag_media_only) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; - case 3: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" ip_address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" port: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" tcpo_only: "); ++stages.back(); if (flag & MTPDdcOption::flag_tcpo_only) { to.add("YES [ BY BIT 2 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 4: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" ip_address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" port: "); ++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; } } @@ -5071,6 +5080,19 @@ void _serialize_messages_botResults(MTPStringLogger &to, int32 stage, int32 lev, } } +void _serialize_exportedMessageLink(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ exportedMessageLink"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" link: "); ++stages.back(); types.push_back(mtpc_string); 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; + } +} + void _serialize_req_pq(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { if (stage) { to.add(",\n").addSpaces(lev); @@ -6448,12 +6470,13 @@ void _serialize_messages_sendMessage(MTPStringLogger &to, int32 stage, int32 lev 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(" no_webpage: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_no_webpage) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; case 2: to.add(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; - case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::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 0 IN FIELD flags ]"); } break; - case 5: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 7: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::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 2 IN FIELD flags ]"); } break; - case 8: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; + case 3: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; + case 4: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::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 0 IN FIELD flags ]"); } break; + case 6: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 8: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::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 2 IN FIELD flags ]"); } break; + case 9: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -6468,11 +6491,12 @@ void _serialize_messages_sendMedia(MTPStringLogger &to, int32 stage, int32 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(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; - case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::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 0 IN FIELD flags ]"); } break; - case 4: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::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 2 IN FIELD flags ]"); } break; + case 2: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; + case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::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 0 IN FIELD flags ]"); } break; + case 5: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::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 2 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -6487,10 +6511,11 @@ void _serialize_messages_forwardMessages(MTPStringLogger &to, int32 stage, int32 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(" broadcast: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; - case 2: to.add(" from_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break; - case 4: 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 5: to.add(" to_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::flag_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; + case 3: to.add(" from_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break; + case 5: 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 6: 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; } } @@ -6663,11 +6688,12 @@ void _serialize_messages_sendInlineBotResult(MTPStringLogger &to, int32 stage, i 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(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; - case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::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 0 IN FIELD flags ]"); } break; - case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::flag_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break; + case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::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 0 IN FIELD flags ]"); } break; + case 5: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); 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; } } @@ -6828,6 +6854,20 @@ void _serialize_channels_toggleInvites(MTPStringLogger &to, int32 stage, int32 l } } +void _serialize_channels_toggleSignatures(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ channels_toggleSignatures"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" enabled: "); ++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; + } +} + void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { if (stage) { to.add(",\n").addSpaces(lev); @@ -7341,6 +7381,20 @@ void _serialize_channels_getParticipant(MTPStringLogger &to, int32 stage, int32 } } +void _serialize_channels_exportMessageLink(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ channels_exportMessageLink"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" channel: "); ++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(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; + } +} + void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { if (stage) { to.add(",\n").addSpaces(lev); @@ -7799,6 +7853,7 @@ namespace { _serializers.insert(mtpc_botInlineMediaResultPhoto, _serialize_botInlineMediaResultPhoto); _serializers.insert(mtpc_botInlineResult, _serialize_botInlineResult); _serializers.insert(mtpc_messages_botResults, _serialize_messages_botResults); + _serializers.insert(mtpc_exportedMessageLink, _serialize_exportedMessageLink); _serializers.insert(mtpc_req_pq, _serialize_req_pq); _serializers.insert(mtpc_req_DH_params, _serialize_req_DH_params); @@ -7929,6 +7984,7 @@ namespace { _serializers.insert(mtpc_channels_kickFromChannel, _serialize_channels_kickFromChannel); _serializers.insert(mtpc_channels_deleteChannel, _serialize_channels_deleteChannel); _serializers.insert(mtpc_channels_toggleInvites, _serialize_channels_toggleInvites); + _serializers.insert(mtpc_channels_toggleSignatures, _serialize_channels_toggleSignatures); _serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats); _serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels); _serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat); @@ -7968,6 +8024,7 @@ namespace { _serializers.insert(mtpc_help_getTermsOfService, _serialize_help_getTermsOfService); _serializers.insert(mtpc_channels_getParticipants, _serialize_channels_getParticipants); _serializers.insert(mtpc_channels_getParticipant, _serialize_channels_getParticipant); + _serializers.insert(mtpc_channels_exportMessageLink, _serialize_channels_exportMessageLink); _serializers.insert(mtpc_rpc_result, _serialize_rpc_result); _serializers.insert(mtpc_msg_container, _serialize_msg_container); diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h index 1f32eb20ec..0f15155a17 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.h +++ b/Telegram/SourceFiles/mtproto/mtpScheme.h @@ -145,7 +145,7 @@ enum { mtpc_chatPhotoEmpty = 0x37c1011c, mtpc_chatPhoto = 0x6153276a, mtpc_messageEmpty = 0x83e5de54, - mtpc_message = 0xc992e15c, + mtpc_message = 0xef11cef6, mtpc_messageService = 0xc06b9607, mtpc_messageMediaEmpty = 0x3ded6320, mtpc_messageMediaPhoto = 0x3d8ce53d, @@ -274,8 +274,8 @@ enum { mtpc_updates_difference = 0xf49ca0, mtpc_updates_differenceSlice = 0xa8fb1981, mtpc_updatesTooLong = 0xe317af7e, - mtpc_updateShortMessage = 0x13e4deaa, - mtpc_updateShortChatMessage = 0x248afa62, + mtpc_updateShortMessage = 0x3afbe9d1, + mtpc_updateShortChatMessage = 0xca2ef195, mtpc_updateShort = 0x78d4dec1, mtpc_updatesCombined = 0x725b04c3, mtpc_updates = 0x74ae4240, @@ -446,6 +446,7 @@ enum { mtpc_botInlineMediaResultPhoto = 0xc5528587, mtpc_botInlineResult = 0x9bebaeb9, mtpc_messages_botResults = 0x1170b0a3, + mtpc_exportedMessageLink = 0x1f486803, mtpc_invokeAfterMsg = 0xcb9f372d, mtpc_invokeAfterMsgs = 0x3dc4b4f0, mtpc_initConnection = 0x69796de9, @@ -604,7 +605,9 @@ enum { mtpc_channels_kickFromChannel = 0xa672de14, mtpc_channels_exportInvite = 0xc7560885, mtpc_channels_deleteChannel = 0xc0111fe3, - mtpc_channels_toggleInvites = 0x49609307 + mtpc_channels_toggleInvites = 0x49609307, + mtpc_channels_exportMessageLink = 0xc846d22d, + mtpc_channels_toggleSignatures = 0x1f69b606 }; // Type forward declarations @@ -1227,6 +1230,9 @@ class MTPDbotInlineResult; class MTPmessages_botResults; class MTPDmessages_botResults; +class MTPexportedMessageLink; +class MTPDexportedMessageLink; + // Boxed types definitions typedef MTPBoxed MTPResPQ; @@ -1388,6 +1394,7 @@ typedef MTPBoxed MTPInputBotInlineResult; typedef MTPBoxed MTPBotInlineMessage; typedef MTPBoxed MTPBotInlineResult; typedef MTPBoxed MTPmessages_BotResults; +typedef MTPBoxed MTPExportedMessageLink; // Type classes definitions @@ -3511,7 +3518,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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _fwd_post, MTPint _via_bot_id, 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; @@ -5717,8 +5724,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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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 _via_bot_id, 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 _fwd_post, MTPint _via_bot_id, 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 _fwd_post, MTPint _via_bot_id, 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); @@ -8956,6 +8963,37 @@ private: }; typedef MTPBoxed MTPmessages_BotResults; +class MTPexportedMessageLink : private mtpDataOwner { +public: + MTPexportedMessageLink(); + MTPexportedMessageLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_exportedMessageLink) : mtpDataOwner(0) { + read(from, end, cons); + } + + MTPDexportedMessageLink &_exportedMessageLink() { + if (!data) throw mtpErrorUninitialized(); + split(); + return *(MTPDexportedMessageLink*)data; + } + const MTPDexportedMessageLink &c_exportedMessageLink() const { + if (!data) throw mtpErrorUninitialized(); + return *(const MTPDexportedMessageLink*)data; + } + + uint32 innerLength() const; + mtpTypeId type() const; + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_exportedMessageLink); + void write(mtpBuffer &to) const; + + typedef void ResponseType; + +private: + explicit MTPexportedMessageLink(MTPDexportedMessageLink *_data); + + friend MTPexportedMessageLink MTP_exportedMessageLink(const MTPstring &_link); +}; +typedef MTPBoxed MTPExportedMessageLink; + // Type constructors with data class MTPDresPQ : public mtpDataImpl { @@ -9823,7 +9861,8 @@ public: flag_verified = (1 << 7), flag_megagroup = (1 << 8), flag_restricted = (1 << 9), - flag_invites_enabled = (1 << 10), + flag_admin_invites = (1 << 10), + flag_signatures = (1 << 11), flag_username = (1 << 6), flag_restriction_reason = (1 << 9), }; @@ -9837,7 +9876,8 @@ public: bool is_verified() const { return vflags.v & flag_verified; } bool is_megagroup() const { return vflags.v & flag_megagroup; } bool is_restricted() const { return vflags.v & flag_restricted; } - bool is_invites_enabled() const { return vflags.v & flag_invites_enabled; } + bool is_admin_invites() const { return vflags.v & flag_admin_invites; } + bool is_signatures() const { return vflags.v & flag_signatures; } bool has_username() const { return vflags.v & flag_username; } bool has_restriction_reason() const { return vflags.v & flag_restriction_reason; } }; @@ -9998,7 +10038,7 @@ class MTPDmessage : public mtpDataImpl { public: MTPDmessage() { } - MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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), vvia_bot_id(_via_bot_id), vreply_to_msg_id(_reply_to_msg_id), vdate(_date), vmessage(_message), vmedia(_media), vreply_markup(_reply_markup), ventities(_entities), vviews(_views) { + MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _fwd_post, MTPint _via_bot_id, 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), vfwd_post(_fwd_post), vvia_bot_id(_via_bot_id), vreply_to_msg_id(_reply_to_msg_id), vdate(_date), vmessage(_message), vmedia(_media), vreply_markup(_reply_markup), ventities(_entities), vviews(_views) { } MTPint vflags; @@ -10007,6 +10047,7 @@ public: MTPPeer vto_id; MTPPeer vfwd_from_id; MTPint vfwd_date; + MTPint vfwd_post; MTPint vvia_bot_id; MTPint vreply_to_msg_id; MTPint vdate; @@ -10021,9 +10062,12 @@ public: flag_out = (1 << 1), flag_mentioned = (1 << 4), flag_media_unread = (1 << 5), + flag_silent = (1 << 13), + flag_post = (1 << 14), flag_from_id = (1 << 8), flag_fwd_from_id = (1 << 2), flag_fwd_date = (1 << 2), + flag_fwd_post = (1 << 12), flag_via_bot_id = (1 << 11), flag_reply_to_msg_id = (1 << 3), flag_media = (1 << 9), @@ -10036,9 +10080,12 @@ public: bool is_out() const { return vflags.v & flag_out; } bool is_mentioned() const { return vflags.v & flag_mentioned; } bool is_media_unread() const { return vflags.v & flag_media_unread; } + bool is_silent() const { return vflags.v & flag_silent; } + bool is_post() const { return vflags.v & flag_post; } bool has_from_id() const { return vflags.v & flag_from_id; } bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; } bool has_fwd_date() const { return vflags.v & flag_fwd_date; } + bool has_fwd_post() const { return vflags.v & flag_fwd_post; } bool has_via_bot_id() const { return vflags.v & flag_via_bot_id; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_media() const { return vflags.v & flag_media; } @@ -11230,7 +11277,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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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), vvia_bot_id(_via_bot_id), 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 _fwd_post, MTPint _via_bot_id, 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), vfwd_post(_fwd_post), vvia_bot_id(_via_bot_id), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { } MTPint vflags; @@ -11242,6 +11289,7 @@ public: MTPint vdate; MTPPeer vfwd_from_id; MTPint vfwd_date; + MTPint vfwd_post; MTPint vvia_bot_id; MTPint vreply_to_msg_id; MTPVector ventities; @@ -11251,8 +11299,10 @@ public: flag_out = (1 << 1), flag_mentioned = (1 << 4), flag_media_unread = (1 << 5), + flag_silent = (1 << 13), flag_fwd_from_id = (1 << 2), flag_fwd_date = (1 << 2), + flag_fwd_post = (1 << 12), flag_via_bot_id = (1 << 11), flag_reply_to_msg_id = (1 << 3), flag_entities = (1 << 7), @@ -11262,8 +11312,10 @@ public: bool is_out() const { return vflags.v & flag_out; } bool is_mentioned() const { return vflags.v & flag_mentioned; } bool is_media_unread() const { return vflags.v & flag_media_unread; } + bool is_silent() const { return vflags.v & flag_silent; } bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; } bool has_fwd_date() const { return vflags.v & flag_fwd_date; } + bool has_fwd_post() const { return vflags.v & flag_fwd_post; } bool has_via_bot_id() const { return vflags.v & flag_via_bot_id; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_entities() const { return vflags.v & flag_entities; } @@ -11273,7 +11325,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), vvia_bot_id(_via_bot_id), 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 _fwd_post, MTPint _via_bot_id, 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), vfwd_post(_fwd_post), vvia_bot_id(_via_bot_id), vreply_to_msg_id(_reply_to_msg_id), ventities(_entities) { } MTPint vflags; @@ -11286,6 +11338,7 @@ public: MTPint vdate; MTPPeer vfwd_from_id; MTPint vfwd_date; + MTPint vfwd_post; MTPint vvia_bot_id; MTPint vreply_to_msg_id; MTPVector ventities; @@ -11295,8 +11348,10 @@ public: flag_out = (1 << 1), flag_mentioned = (1 << 4), flag_media_unread = (1 << 5), + flag_silent = (1 << 13), flag_fwd_from_id = (1 << 2), flag_fwd_date = (1 << 2), + flag_fwd_post = (1 << 12), flag_via_bot_id = (1 << 11), flag_reply_to_msg_id = (1 << 3), flag_entities = (1 << 7), @@ -11306,8 +11361,10 @@ public: bool is_out() const { return vflags.v & flag_out; } bool is_mentioned() const { return vflags.v & flag_mentioned; } bool is_media_unread() const { return vflags.v & flag_media_unread; } + bool is_silent() const { return vflags.v & flag_silent; } bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; } bool has_fwd_date() const { return vflags.v & flag_fwd_date; } + bool has_fwd_post() const { return vflags.v & flag_fwd_post; } bool has_via_bot_id() const { return vflags.v & flag_via_bot_id; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_entities() const { return vflags.v & flag_entities; } @@ -11442,10 +11499,12 @@ public: enum { flag_ipv6 = (1 << 0), flag_media_only = (1 << 1), + flag_tcpo_only = (1 << 2), }; bool is_ipv6() const { return vflags.v & flag_ipv6; } bool is_media_only() const { return vflags.v & flag_media_only; } + bool is_tcpo_only() const { return vflags.v & flag_tcpo_only; } }; class MTPDconfig : public mtpDataImpl { @@ -13023,6 +13082,16 @@ public: bool has_next_offset() const { return vflags.v & flag_next_offset; } }; +class MTPDexportedMessageLink : public mtpDataImpl { +public: + MTPDexportedMessageLink() { + } + MTPDexportedMessageLink(const MTPstring &_link) : vlink(_link) { + } + + MTPstring vlink; +}; + // RPC methods class MTPreq_pq { // RPC method 'req_pq' @@ -16206,6 +16275,7 @@ public: enum { flag_no_webpage = (1 << 1), flag_broadcast = (1 << 4), + flag_silent = (1 << 5), flag_reply_to_msg_id = (1 << 0), flag_reply_markup = (1 << 2), flag_entities = (1 << 3), @@ -16213,6 +16283,7 @@ public: bool is_no_webpage() const { return vflags.v & flag_no_webpage; } bool is_broadcast() const { return vflags.v & flag_broadcast; } + bool is_silent() const { return vflags.v & flag_silent; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_reply_markup() const { return vflags.v & flag_reply_markup; } bool has_entities() const { return vflags.v & flag_entities; } @@ -16275,11 +16346,13 @@ public: enum { flag_broadcast = (1 << 4), + flag_silent = (1 << 5), flag_reply_to_msg_id = (1 << 0), flag_reply_markup = (1 << 2), }; bool is_broadcast() const { return vflags.v & flag_broadcast; } + bool is_silent() const { return vflags.v & flag_silent; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_reply_markup() const { return vflags.v & flag_reply_markup; } @@ -16338,9 +16411,11 @@ public: enum { flag_broadcast = (1 << 4), + flag_silent = (1 << 5), }; bool is_broadcast() const { return vflags.v & flag_broadcast; } + bool is_silent() const { return vflags.v & flag_silent; } uint32 innerLength() const { return vflags.innerLength() + vfrom_peer.innerLength() + vid.innerLength() + vrandom_id.innerLength() + vto_peer.innerLength(); @@ -18230,10 +18305,12 @@ public: enum { flag_broadcast = (1 << 4), + flag_silent = (1 << 5), flag_reply_to_msg_id = (1 << 0), }; bool is_broadcast() const { return vflags.v & flag_broadcast; } + bool is_silent() const { return vflags.v & flag_silent; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } uint32 innerLength() const { @@ -20133,6 +20210,90 @@ public: } }; +class MTPchannels_exportMessageLink { // RPC method 'channels.exportMessageLink' +public: + MTPInputChannel vchannel; + MTPint vid; + + MTPchannels_exportMessageLink() { + } + MTPchannels_exportMessageLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_exportMessageLink) { + read(from, end, cons); + } + MTPchannels_exportMessageLink(const MTPInputChannel &_channel, MTPint _id) : vchannel(_channel), vid(_id) { + } + + uint32 innerLength() const { + return vchannel.innerLength() + vid.innerLength(); + } + mtpTypeId type() const { + return mtpc_channels_exportMessageLink; + } + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_exportMessageLink) { + vchannel.read(from, end); + vid.read(from, end); + } + void write(mtpBuffer &to) const { + vchannel.write(to); + vid.write(to); + } + + typedef MTPExportedMessageLink ResponseType; +}; +class MTPchannels_ExportMessageLink : public MTPBoxed { +public: + MTPchannels_ExportMessageLink() { + } + MTPchannels_ExportMessageLink(const MTPchannels_exportMessageLink &v) : MTPBoxed(v) { + } + MTPchannels_ExportMessageLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { + } + MTPchannels_ExportMessageLink(const MTPInputChannel &_channel, MTPint _id) : MTPBoxed(MTPchannels_exportMessageLink(_channel, _id)) { + } +}; + +class MTPchannels_toggleSignatures { // RPC method 'channels.toggleSignatures' +public: + MTPInputChannel vchannel; + MTPBool venabled; + + MTPchannels_toggleSignatures() { + } + MTPchannels_toggleSignatures(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_toggleSignatures) { + read(from, end, cons); + } + MTPchannels_toggleSignatures(const MTPInputChannel &_channel, MTPBool _enabled) : vchannel(_channel), venabled(_enabled) { + } + + uint32 innerLength() const { + return vchannel.innerLength() + venabled.innerLength(); + } + mtpTypeId type() const { + return mtpc_channels_toggleSignatures; + } + void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_toggleSignatures) { + vchannel.read(from, end); + venabled.read(from, end); + } + void write(mtpBuffer &to) const { + vchannel.write(to); + venabled.write(to); + } + + typedef MTPUpdates ResponseType; +}; +class MTPchannels_ToggleSignatures : public MTPBoxed { +public: + MTPchannels_ToggleSignatures() { + } + MTPchannels_ToggleSignatures(const MTPchannels_toggleSignatures &v) : MTPBoxed(v) { + } + MTPchannels_ToggleSignatures(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { + } + MTPchannels_ToggleSignatures(const MTPInputChannel &_channel, MTPBool _enabled) : MTPBoxed(MTPchannels_toggleSignatures(_channel, _enabled)) { + } +}; + // Inline methods definition inline MTPresPQ::MTPresPQ() : mtpDataOwner(new MTPDresPQ()) { @@ -22885,7 +23046,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_via_bot_id() ? v.vvia_bot_id.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); + 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_fwd_post() ? v.vfwd_post.innerLength() : 0) + (v.has_via_bot_id() ? v.vvia_bot_id.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()); @@ -22915,6 +23076,7 @@ inline void MTPmessage::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vto_id.read(from, end); 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_fwd_post()) { v.vfwd_post.read(from, end); } else { v.vfwd_post = MTPint(); } if (v.has_via_bot_id()) { v.vvia_bot_id.read(from, end); } else { v.vvia_bot_id = 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); @@ -22951,6 +23113,7 @@ inline void MTPmessage::write(mtpBuffer &to) const { v.vto_id.write(to); if (v.has_fwd_from_id()) v.vfwd_from_id.write(to); if (v.has_fwd_date()) v.vfwd_date.write(to); + if (v.has_fwd_post()) v.vfwd_post.write(to); if (v.has_via_bot_id()) v.vvia_bot_id.write(to); if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to); v.vdate.write(to); @@ -22988,8 +23151,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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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, _via_bot_id, _reply_to_msg_id, _date, _message, _media, _reply_markup, _entities, _views)); +inline MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _fwd_post, MTPint _via_bot_id, 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, _fwd_post, _via_bot_id, _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)); @@ -25946,11 +26109,11 @@ inline uint32 MTPupdates::innerLength() const { switch (_type) { case mtpc_updateShortMessage: { const MTPDupdateShortMessage &v(c_updateShortMessage()); - return v.vflags.innerLength() + v.vid.innerLength() + v.vuser_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_via_bot_id() ? v.vvia_bot_id.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0); + return v.vflags.innerLength() + v.vid.innerLength() + v.vuser_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_fwd_post() ? v.vfwd_post.innerLength() : 0) + (v.has_via_bot_id() ? v.vvia_bot_id.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0); } case mtpc_updateShortChatMessage: { const MTPDupdateShortChatMessage &v(c_updateShortChatMessage()); - return v.vflags.innerLength() + v.vid.innerLength() + v.vfrom_id.innerLength() + v.vchat_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_via_bot_id() ? v.vvia_bot_id.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0); + return v.vflags.innerLength() + v.vid.innerLength() + v.vfrom_id.innerLength() + v.vchat_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_fwd_post() ? v.vfwd_post.innerLength() : 0) + (v.has_via_bot_id() ? v.vvia_bot_id.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + (v.has_entities() ? v.ventities.innerLength() : 0); } case mtpc_updateShort: { const MTPDupdateShort &v(c_updateShort()); @@ -25991,6 +26154,7 @@ inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vdate.read(from, end); 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_fwd_post()) { v.vfwd_post.read(from, end); } else { v.vfwd_post = MTPint(); } if (v.has_via_bot_id()) { v.vvia_bot_id.read(from, end); } else { v.vvia_bot_id = 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(); } @@ -26008,6 +26172,7 @@ inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpType v.vdate.read(from, end); 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_fwd_post()) { v.vfwd_post.read(from, end); } else { v.vfwd_post = MTPint(); } if (v.has_via_bot_id()) { v.vvia_bot_id.read(from, end); } else { v.vvia_bot_id = 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(); } @@ -26064,6 +26229,7 @@ inline void MTPupdates::write(mtpBuffer &to) const { v.vdate.write(to); if (v.has_fwd_from_id()) v.vfwd_from_id.write(to); if (v.has_fwd_date()) v.vfwd_date.write(to); + if (v.has_fwd_post()) v.vfwd_post.write(to); if (v.has_via_bot_id()) v.vvia_bot_id.write(to); if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to); if (v.has_entities()) v.ventities.write(to); @@ -26080,6 +26246,7 @@ inline void MTPupdates::write(mtpBuffer &to) const { v.vdate.write(to); if (v.has_fwd_from_id()) v.vfwd_from_id.write(to); if (v.has_fwd_date()) v.vfwd_date.write(to); + if (v.has_fwd_post()) v.vfwd_post.write(to); if (v.has_via_bot_id()) v.vvia_bot_id.write(to); if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to); if (v.has_entities()) v.ventities.write(to); @@ -26145,11 +26312,11 @@ 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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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, _via_bot_id, _reply_to_msg_id, _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 _fwd_post, MTPint _via_bot_id, 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, _fwd_post, _via_bot_id, _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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _via_bot_id, 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, _via_bot_id, _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, const MTPPeer &_fwd_from_id, MTPint _fwd_date, MTPint _fwd_post, MTPint _via_bot_id, 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, _fwd_post, _via_bot_id, _reply_to_msg_id, _entities)); } inline MTPupdates MTP_updateShort(const MTPUpdate &_update, MTPint _date) { return MTPupdates(new MTPDupdateShort(_update, _date)); @@ -30417,5 +30584,32 @@ inline MTPmessages_botResults MTP_messages_botResults(MTPint _flags, const MTPlo return MTPmessages_botResults(new MTPDmessages_botResults(_flags, _query_id, _next_offset, _results)); } +inline MTPexportedMessageLink::MTPexportedMessageLink() : mtpDataOwner(new MTPDexportedMessageLink()) { +} + +inline uint32 MTPexportedMessageLink::innerLength() const { + const MTPDexportedMessageLink &v(c_exportedMessageLink()); + return v.vlink.innerLength(); +} +inline mtpTypeId MTPexportedMessageLink::type() const { + return mtpc_exportedMessageLink; +} +inline void MTPexportedMessageLink::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { + if (cons != mtpc_exportedMessageLink) throw mtpErrorUnexpected(cons, "MTPexportedMessageLink"); + + if (!data) setData(new MTPDexportedMessageLink()); + MTPDexportedMessageLink &v(_exportedMessageLink()); + v.vlink.read(from, end); +} +inline void MTPexportedMessageLink::write(mtpBuffer &to) const { + const MTPDexportedMessageLink &v(c_exportedMessageLink()); + v.vlink.write(to); +} +inline MTPexportedMessageLink::MTPexportedMessageLink(MTPDexportedMessageLink *_data) : mtpDataOwner(_data) { +} +inline MTPexportedMessageLink MTP_exportedMessageLink(const MTPstring &_link) { + return MTPexportedMessageLink(new MTPDexportedMessageLink(_link)); +} + // Human-readable text serialization void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons); diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 499823df8e..8c3a8a5dda 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -209,7 +209,7 @@ userStatusLastMonth#77ebc742 = UserStatus; chatEmpty#9ba2d800 id:int = Chat; chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat; chatForbidden#7328bdb id:int title:string = Chat; -channel#4b1b7506 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true invites_enabled:flags.10?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat; +channel#4b1b7506 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true admin_invites:flags.10?true signatures:flags.11?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat; channelForbidden#2d85832c id:int access_hash:long title:string = Chat; chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector = ChatFull; @@ -226,7 +226,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto; messageEmpty#83e5de54 id:int = Message; -message#c992e15c flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int from_id:flags.8?int to_id:Peer fwd_from_id:flags.2?Peer fwd_date:flags.2?int via_bot_id:flags.11?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; +message#ef11cef6 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from_id:flags.2?Peer fwd_date:flags.2?int fwd_post:flags.12?int via_bot_id:flags.11?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:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true id:int from_id:flags.8?int to_id:Peer date:int action:MessageAction = Message; messageMediaEmpty#3ded6320 = MessageMedia; @@ -391,8 +391,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#13e4deaa flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true 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 via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; -updateShortChatMessage#248afa62 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true 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 via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; +updateShortMessage#3afbe9d1 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true 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 fwd_post:flags.12?int via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector = Updates; +updateShortChatMessage#ca2ef195 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true 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 fwd_post:flags.12?int via_bot_id:flags.11?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; @@ -405,7 +405,7 @@ photos.photo#20212ca8 photo:Photo users:Vector = photos.Photo; upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File; -dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true id:int ip_address:string port:int = DcOption; +dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true id:int ip_address:string port:int = DcOption; config#6bbc5f8 date:int expires:int test_mode:Bool this_dc:int dc_options:Vector chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int disabled_features:Vector = Config; @@ -639,6 +639,8 @@ botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string desc messages.botResults#1170b0a3 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string results:Vector = messages.BotResults; +exportedMessageLink#1f486803 link:string = ExportedMessageLink; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -714,9 +716,9 @@ messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHis messages.deleteMessages#a5f18925 id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; -messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true broadcast:flags.4?true 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:# broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; -messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer = Updates; +messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true broadcast:flags.4?true silent:flags.5?true 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:# broadcast:flags.4?true silent:flags.5?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; +messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true silent:flags.5?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getChats#3c6aa187 id:Vector = messages.Chats; messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull; @@ -760,7 +762,7 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs; messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool; messages.getInlineBotResults#9324600d bot:InputUser query:string offset:string = messages.BotResults; messages.setInlineBotResults#3f23ec12 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector cache_time:int next_offset:flags.2?string = Bool; -messages.sendInlineBotResult#b16e06fe flags:# broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates; +messages.sendInlineBotResult#b16e06fe flags:# broadcast:flags.4?true silent:flags.5?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates; updates.getState#edd4882a = updates.State; updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference; @@ -810,3 +812,5 @@ channels.kickFromChannel#a672de14 channel:InputChannel user_id:InputUser kicked: channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite; channels.deleteChannel#c0111fe3 channel:InputChannel = Updates; channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates; +channels.exportMessageLink#c846d22d channel:InputChannel id:int = ExportedMessageLink; +channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates; diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index f00799cf63..d0246cf776 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1306,16 +1306,17 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (_selectedMsgId) repaintItem(_selectedMsgId, -1); } else if (!ignoreMousedItem && App::mousedItem() && App::mousedItem()->channelId() == itemChannel(_mousedItem) && App::mousedItem()->id == itemMsgId(_mousedItem)) { _menu = new PopupMenu(); - if ((_contextMenuLnk && dynamic_cast(_contextMenuLnk.data()))) { + QLatin1String linktype = _contextMenuLnk ? _contextMenuLnk->type() : qstr(""); + if (linktype == qstr("TextLink") || linktype == qstr("LocationLink")) { _menu->addAction(lang(lng_context_open_link), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_link), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if ((_contextMenuLnk && dynamic_cast(_contextMenuLnk.data()))) { + } else if (linktype == qstr("EmailLink")) { _menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + } else if (linktype == qstr("MentionLink")) { _menu->addAction(lang(lng_context_open_mention), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true); - } else if (_contextMenuLnk && dynamic_cast(_contextMenuLnk.data())) { + } else if (linktype == qstr("HashtagLink")) { _menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_hashtag), this, SLOT(copyContextUrl()))->setEnabled(true); } else { diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 313709f181..665ed2b668 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -1077,6 +1077,15 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) { connect(box, SIGNAL(confirmed()), this, SLOT(onKickConfirm())); Ui::showLayer(box); } + + _kickDown = 0; + if (!_photoLink && (_peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator))) { + setCursor((_kickOver || _kickDown || textlnkOver()) ? style::cur_pointer : style::cur_default); + } else { + setCursor((_kickOver || _kickDown || _photoOver || textlnkOver()) ? style::cur_pointer : style::cur_default); + } + update(); + if (textlnkDown()) { TextLinkPtr lnk = textlnkDown(); textlnkDown(TextLinkPtr()); @@ -1087,17 +1096,10 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) { if (reBotCommand().match(lnk->encoded()).hasMatch()) { Ui::showPeerHistory(_peer, ShowAtTheEndMsgId); } - lnk->onClick(e->button()); + App::activateTextLink(lnk, e->button()); } } } - _kickDown = 0; - if (!_photoLink && (_peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator))) { - setCursor((_kickOver || _kickDown || textlnkOver()) ? style::cur_pointer : style::cur_default); - } else { - setCursor((_kickOver || _kickDown || _photoOver || textlnkOver()) ? style::cur_pointer : style::cur_default); - } - update(); } void ProfileInner::onKickConfirm() { diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index 6b1e982da9..146e6fc759 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -1488,3 +1488,7 @@ bool linuxMoveFile(const char *from, const char *to) { return true; } + +bool psLaunchMaps(const QString &lat, const QString &lon) { + return false; +} diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h index 8a527b1f73..748a5639c9 100644 --- a/Telegram/SourceFiles/pspecific_linux.h +++ b/Telegram/SourceFiles/pspecific_linux.h @@ -194,3 +194,5 @@ public: }; bool linuxMoveFile(const char *from, const char *to); + +bool psLaunchMaps(const QString &lat, const QString &lon); diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 84349d6160..edaaa92ab1 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -926,3 +926,7 @@ QString strNeedToRefresh2() { const uint32 letters[] = { 0x8F001546, 0xAF007A49, 0xB8002B5F, 0x1A000B54, 0xD003E49, 0xE0003663, 0x4900796F, 0x500836E, 0x9A00D156, 0x5E00FF69, 0x5900C765, 0x3D00D177 }; return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0])); } + +bool psLaunchMaps(const QString &lat, const QString &lon) { + return false; +} diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index 70ca3ade6d..979e9825fd 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -223,3 +223,5 @@ QString strStyleOfInterface(); QString strNeedToReload(); QString strNeedToRefresh1(); QString strNeedToRefresh2(); + +bool psLaunchMaps(const QString &lat, const QString &lon); diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 044827de67..a2c4e879ee 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -3650,3 +3650,7 @@ bool InitToastManager() { QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); return true; } + +bool psLaunchMaps(const QString &lat, const QString &lon) { + return QDesktopServices::openUrl(qsl("bingmaps:?lvl=16&collection=point.") + lat + '_' + lon + '_' + qsl("Point")); +} diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index ce46b80cc9..90bc466c46 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -194,3 +194,5 @@ public: } }; + +bool psLaunchMaps(const QString &lat, const QString &lon); diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 3803850684..1c05b266ab 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -688,11 +688,12 @@ void PhotoCancelLink::onClick(Qt::MouseButton button) const { if (!data->date) return; if (data->uploading()) { - HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0); - if (HistoryMessage *msg = item->toHistoryMessage()) { - if (msg->getMedia() && msg->getMedia()->type() == MediaTypePhoto && static_cast(msg->getMedia())->photo() == data) { - App::contextItem(item); - App::main()->deleteLayer(-2); + if (HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0)) { + if (HistoryMessage *msg = item->toHistoryMessage()) { + if (msg->getMedia() && msg->getMedia()->type() == MediaTypePhoto && static_cast(msg->getMedia())->photo() == data) { + App::contextItem(item); + App::main()->deleteLayer(-2); + } } } } else { @@ -964,11 +965,12 @@ void DocumentCancelLink::onClick(Qt::MouseButton button) const { if (!data->date) return; if (data->uploading()) { - HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0); - if (HistoryMessage *msg = item->toHistoryMessage()) { - if (msg->getMedia() && msg->getMedia()->getDocument() == data) { - App::contextItem(item); - App::main()->deleteLayer(-2); + if (HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0)) { + if (HistoryMessage *msg = item->toHistoryMessage()) { + if (msg->getMedia() && msg->getMedia()->getDocument() == data) { + App::contextItem(item); + App::main()->deleteLayer(-2); + } } } } else { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 625b300db3..3afef5e2b1 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -156,6 +156,7 @@ inline bool isClientMsgId(MsgId id) { } static const MsgId ShowAtTheEndMsgId = -0x40000000; static const MsgId SwitchAtTopMsgId = -0x3FFFFFFF; +static const MsgId ShowAtProfileMsgId = -0x3FFFFFFE; static const MsgId ServerMaxMsgId = 0x3FFFFFFF; static const MsgId ShowAtUnreadMsgId = 0; @@ -622,12 +623,15 @@ public: bool canViewParticipants() const { return flagsFull & MTPDchannelFull::flag_can_view_participants; } + bool addsSignature() const { + return flags & MTPDchannel::flag_signatures; + } bool isForbidden; bool isVerified() const { return flags & MTPDchannel::flag_verified; } bool canAddParticipants() const { - return amCreator() || amEditor() || (flags & MTPDchannel::flag_invites_enabled); + return amCreator() || amEditor() || (flags & MTPDchannel::flag_admin_invites); } // ImagePtr photoFull; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 52f823b27e..83679b68de 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -210,8 +210,8 @@ void NotifyWindow::updateNotifyDisplay() { item->drawInDialog(p, r, active, textCachedFor, itemTextCache); } else { p.setFont(st::dlgHistFont->f); - if (item->hasFromName() && !item->fromChannel()) { - itemTextCache.setText(st::dlgHistFont, item->from()->name); + if (item->hasFromName() && !item->isPost()) { + itemTextCache.setText(st::dlgHistFont, item->author()->name); p.setPen(st::dlgSystemColor->p); itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dlgHistFont->height); r.setTop(r.top() + st::dlgHistFont->height); @@ -363,9 +363,22 @@ NotifyWindow::~NotifyWindow() { if (App::wnd()) App::wnd()->notifyShowNext(this); } -Window::Window(QWidget *parent) : PsMainWindow(parent), _serviceHistoryRequest(0), title(0), -_passcode(0), intro(0), main(0), settings(0), layerBg(0), _isActive(false), -_connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shouldLockAt(0), _mediaView(0) { +Window::Window(QWidget *parent) : PsMainWindow(parent) +, _serviceHistoryRequest(0) +, title(0) +, _passcode(0) +, intro(0) +, main(0) +, settings(0) +, layerBg(0) +, _stickerPreview(0) +, _isActive(false) +, _connecting(0) +, _clearManager(0) +, dragging(false) +, _inactivePress(false) +, _shouldLockAt(0) +, _mediaView(0) { icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); @@ -842,6 +855,23 @@ bool Window::ui_isMediaViewShown() { return _mediaView && !_mediaView->isHidden(); } +void Window::ui_showStickerPreview(DocumentData *sticker) { + if (!sticker || ((!sticker->isAnimation() || !sticker->loaded()) && !sticker->sticker())) return; + if (!_stickerPreview) { + _stickerPreview = new StickerPreviewWidget(this); + resizeEvent(0); + } + if (_stickerPreview->isHidden()) { + fixOrder(); + } + _stickerPreview->showPreview(sticker); +} + +void Window::ui_hideStickerPreview() { + if (!_stickerPreview) return; + _stickerPreview->hidePreview(); +} + void Window::showConnecting(const QString &text, const QString &reconnect) { if (_connecting) { _connecting->set(text, reconnect); @@ -1169,6 +1199,7 @@ void Window::layerFinishedHide(BackgroundWidget *was) { void Window::fixOrder() { title->raise(); if (layerBg) layerBg->raise(); + if (_stickerPreview) _stickerPreview->raise(); if (_connecting) _connecting->raise(); } @@ -1242,6 +1273,7 @@ void Window::resizeEvent(QResizeEvent *e) { } title->setGeometry(0, 0, width(), st::titleHeight); if (layerBg) layerBg->resize(width(), height()); + if (_stickerPreview) _stickerPreview->setGeometry(0, title->height(), width(), height() - title->height()); if (_connecting) _connecting->setGeometry(0, height() - _connecting->height(), _connecting->width(), _connecting->height()); emit resized(QSize(width(), height() - st::titleHeight)); } @@ -1317,6 +1349,11 @@ void Window::notifySchedule(History *history, HistoryItem *item) { PeerData *notifyByFrom = (!history->peer->isUser() && item->mentionsMe()) ? item->from() : 0; + if (item->isSilent()) { + history->popNotification(item); + return; + } + bool haveSetting = (history->peer->notify != UnknownNotifySettings); if (haveSetting) { if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) { @@ -1824,6 +1861,7 @@ void Window::updateIsActive(int timeout) { Window::~Window() { notifyClearFast(); + deleteAndMark(_stickerPreview); delete _clearManager; delete _connecting; delete _mediaView; @@ -2730,7 +2768,7 @@ void LastCrashedWindow::onUpdateFailed() { void LastCrashedWindow::onContinue() { if (SignalHandlers::restart() == SignalHandlers::CantOpen) { new NotStartedWindow(); - } else { + } else if (!Global::started()) { Sandbox::launch(); } close(); diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index af821859f0..ab34c00d92 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -121,6 +121,8 @@ private: typedef QList NotifyWindows; +class StickerPreviewWidget; + class Window : public PsMainWindow { Q_OBJECT @@ -239,6 +241,8 @@ public: void ui_showLayer(LayeredWidget *box, ShowLayerOptions options); bool ui_isLayerShown(); bool ui_isMediaViewShown(); + void ui_showStickerPreview(DocumentData *sticker); + void ui_hideStickerPreview(); public slots: @@ -311,6 +315,7 @@ private: MainWidget *main; SettingsWidget *settings; BackgroundWidget *layerBg; + StickerPreviewWidget *_stickerPreview; QTimer _isActiveTimer; bool _isActive;