diff --git a/Telegram/SourceFiles/core/vector_of_moveable.h b/Telegram/SourceFiles/core/vector_of_moveable.h index 412d87b35..608bb0796 100644 --- a/Telegram/SourceFiles/core/vector_of_moveable.h +++ b/Telegram/SourceFiles/core/vector_of_moveable.h @@ -141,7 +141,10 @@ private: void reallocate(int newCapacity) { auto newPlainData = operator new[](newCapacity * sizeof(T)); for (int i = 0; i < _size; ++i) { - *(reinterpret_cast(newPlainData) + i) = std_::move(*(data() + i)); + auto oldLocation = data() + i; + auto newLocation = reinterpret_cast(newPlainData) + i; + new (newLocation) T(std_::move(*oldLocation)); + oldLocation->~T(); } std::swap(_plaindata, newPlainData); _capacity = newCapacity; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 58175e636..1e8a6239d 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -33,6 +33,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Q_DECLARE_METATYPE(ClickHandlerPtr); Q_DECLARE_METATYPE(Qt::MouseButton); +Q_DECLARE_METATYPE(Ui::ShowWay); namespace App { @@ -253,13 +254,14 @@ void showPeerOverview(const PeerId &peer, MediaOverviewType type) { } } -void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) { - if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, back); +void showPeerHistory(const PeerId &peer, MsgId msgId, ShowWay way) { + if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, way); } -void showPeerHistoryAsync(const PeerId &peer, MsgId msgId) { +void showPeerHistoryAsync(const PeerId &peer, MsgId msgId, ShowWay way) { if (MainWidget *m = App::main()) { - QMetaObject::invokeMethod(m, "ui_showPeerHistoryAsync", Qt::QueuedConnection, Q_ARG(quint64, peer), Q_ARG(qint32, msgId)); + qRegisterMetaType(); + QMetaObject::invokeMethod(m, "ui_showPeerHistoryAsync", Qt::QueuedConnection, Q_ARG(quint64, peer), Q_ARG(qint32, msgId), Q_ARG(Ui::ShowWay, way)); } } diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 71cd432e5..59a990bbd 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -83,22 +83,27 @@ inline void showPeerOverview(const History *history, MediaOverviewType type) { showPeerOverview(history->peer->id, type); } -void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false); -inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) { - showPeerHistory(peer->id, msgId, back); +enum class ShowWay { + ClearStack, + Forward, + Backward, +}; +void showPeerHistory(const PeerId &peer, MsgId msgId, ShowWay way = ShowWay::ClearStack); +inline void showPeerHistory(const PeerData *peer, MsgId msgId, ShowWay way = ShowWay::ClearStack) { + showPeerHistory(peer->id, msgId, way); } -inline void showPeerHistory(const History *history, MsgId msgId, bool back = false) { - showPeerHistory(history->peer->id, msgId, back); +inline void showPeerHistory(const History *history, MsgId msgId, ShowWay way = ShowWay::ClearStack) { + showPeerHistory(history->peer->id, msgId, way); } -inline void showPeerHistoryAtItem(const HistoryItem *item) { - showPeerHistory(item->history()->peer->id, item->id); +inline void showPeerHistoryAtItem(const HistoryItem *item, ShowWay way = ShowWay::ClearStack) { + showPeerHistory(item->history()->peer->id, item->id, way); } -void showPeerHistoryAsync(const PeerId &peer, MsgId msgId); +void showPeerHistoryAsync(const PeerId &peer, MsgId msgId, ShowWay way = ShowWay::ClearStack); inline void showChatsList() { - showPeerHistory(PeerId(0), 0); + showPeerHistory(PeerId(0), 0, ShowWay::ClearStack); } inline void showChatsListAsync() { - showPeerHistoryAsync(PeerId(0), 0); + showPeerHistoryAsync(PeerId(0), 0, ShowWay::ClearStack); } PeerData *getPeerForMouseAction(); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index a29b92053..f298cde33 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -5178,7 +5178,7 @@ int HistorySticker::additionalWidth(const HistoryMessageVia *via, const HistoryM } void SendMessageClickHandler::onClickImpl() const { - Ui::showPeerHistory(peer()->id, ShowAtUnreadMsgId); + Ui::showPeerHistory(peer()->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); } void AddContactClickHandler::onClickImpl() const { diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 47a8fe198..6748fe79c 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3761,7 +3761,7 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic QString title = stickerSetTitle(set); if (it == sets.cend()) { auto clientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded; - if (unread.contains(set.vid.v)) { + if (unread.contains(set.vid.v) || !(set.vflags.v & MTPDstickerSet::Flag::f_installed)) { clientFlags |= MTPDstickerSet_ClientFlag::f_unread; } it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | clientFlags)); @@ -4673,7 +4673,7 @@ bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) { PeerData *was = _peer; - Ui::showChatsList(); + App::main()->showBackFromStack(); Ui::showLayer(new InformBox(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible))); return true; } @@ -4685,7 +4685,7 @@ bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId _preloadDownRequest = 0; } else if (_firstLoadRequest == requestId) { _firstLoadRequest = 0; - Ui::showChatsList(); + App::main()->showBackFromStack(); } else if (_delayedShowAtRequest == requestId) { _delayedShowAtRequest = 0; } @@ -5704,7 +5704,7 @@ void HistoryWidget::botCallbackDone(BotCallbackInfo info, const MTPmessages_BotC Ui::Toast::Show(App::wnd(), toast); } } else if (answerData.has_url()) { - UrlClickHandler::doOpen(qs(answerData.vurl)); + HiddenUrlClickHandler(qs(answerData.vurl)).onClick(Qt::LeftButton); } } } @@ -6139,7 +6139,7 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { if (!_history) return; - int32 increaseLeft = Adaptive::OneColumn() ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0; + int32 increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0; decreaseWidth += increaseLeft; QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); p.setFont(st::dialogsTextFont); @@ -6154,7 +6154,7 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { p.setPen(st::dialogsNameFg); _peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - if (Adaptive::OneColumn()) { + if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); p.drawSprite(QPoint((st::topBarForwardPadding.right() - st::topBarBackwardImg.pxWidth()) / 2, (st::topBarHeight - st::topBarBackwardImg.pxHeight()) / 2), st::topBarBackwardImg); } else { @@ -6164,7 +6164,7 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { } QRect HistoryWidget::getMembersShowAreaGeometry() const { - int increaseLeft = Adaptive::OneColumn() ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0; + int increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0; int membersTextLeft = st::topBarForwardPadding.left() + increaseLeft; int membersTextTop = st::topBarHeight - st::topBarForwardPadding.bottom() - st::dialogsTextFont->height; int membersTextWidth = _titlePeerTextWidth; @@ -6210,8 +6210,8 @@ void HistoryWidget::onMembersDropdownHidden() { } void HistoryWidget::topBarClick() { - if (Adaptive::OneColumn()) { - Ui::showChatsList(); + if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { + App::main()->showBackFromStack(); } else { if (_history) Ui::showPeerProfile(_peer); } @@ -6763,10 +6763,10 @@ void HistoryWidget::onReportSpamClear() { if (_clearPeer->isUser()) { App::main()->deleteConversation(_clearPeer); } else if (_clearPeer->isChat()) { - Ui::showChatsList(); + App::main()->showBackFromStack(); MTP::send(MTPmessages_DeleteChatUser(_clearPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _clearPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _clearPeer)); } else if (_clearPeer->isChannel()) { - Ui::showChatsList(); + App::main()->showBackFromStack(); if (_clearPeer->migrateFrom()) { App::main()->deleteConversation(_clearPeer->migrateFrom()); } @@ -7294,7 +7294,7 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { e->ignore(); } else if (e->key() == Qt::Key_Back) { - Ui::showChatsList(); + App::main()->showBackFromStack(); emit cancelled(); } else if (e->key() == Qt::Key_PageDown) { _scroll.keyPressEvent(e); @@ -8072,7 +8072,7 @@ void HistoryWidget::onCancel() { } else if (!_fieldAutocomplete->isHidden()) { _fieldAutocomplete->hideStart(); } else { - Ui::showChatsList(); + App::main()->showBackFromStack(); emit cancelled(); } } @@ -8110,7 +8110,7 @@ void HistoryWidget::peerUpdated(PeerData *data) { } QString restriction = _peer->restrictionReason(); if (!restriction.isEmpty()) { - Ui::showChatsList(); + App::main()->showBackFromStack(); Ui::showLayer(new InformBox(restriction)); return; } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f5a74cc59..23e417042 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1519,8 +1519,8 @@ void MainWidget::onSharePhoneWithBot(PeerData *recipient) { onShareContact(recipient->id, App::self()); } -void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId) { - Ui::showPeerHistory(peerId, showAtMsgId); +void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way) { + Ui::showPeerHistory(peerId, showAtMsgId, way); } void MainWidget::ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId) { @@ -2016,7 +2016,7 @@ void MainWidget::ctrlEnterSubmitUpdated() { _history->updateFieldSubmitSettings(); } -void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) { +void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way) { if (PeerData *peer = App::peerLoaded(peerId)) { if (peer->migrateTo()) { peer = peer->migrateTo(); @@ -2030,8 +2030,37 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac return; } } - if (!back && (!peerId || (_stack.size() == 1 && _stack[0]->type() == HistoryStackItem && _stack[0]->peer->id == peerId))) { - back = true; + + bool back = (way == Ui::ShowWay::Backward || !peerId); + bool foundInStack = !peerId; + if (foundInStack || (way == Ui::ShowWay::ClearStack)) { + for_const (auto &item, _stack) { + clearBotStartToken(item->peer); + } + _stack.clear(); + } else { + for (int i = 0, s = _stack.size(); i < s; ++i) { + if (_stack.at(i)->type() == HistoryStackItem && _stack.at(i)->peer->id == peerId) { + foundInStack = true; + while (_stack.size() > i) { + clearBotStartToken(_stack.back()->peer); + _stack.pop_back(); + } + if (!back) { + back = true; + } + break; + } + } + } + + if (back || (way == Ui::ShowWay::ClearStack)) { + dlgUpdated(); + _peerInStack = nullptr; + _msgIdInStack = 0; + dlgUpdated(); + } else { + saveSectionInStack(); } PeerData *wasActivePeer = activePeer(); @@ -2043,10 +2072,12 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac } Window::SectionSlideParams animationParams; - if (!_a_show.animating() && ((_history->isHidden() && (_wideSection || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)))) { + if (!_a_show.animating() && ((_history->isHidden() && (_wideSection || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)) || back || (way == Ui::ShowWay::Forward))) { animationParams = prepareHistoryAnimation(peerId); } - if (_history->peer() && _history->peer()->id != peerId) clearBotStartToken(_history->peer()); + if (_history->peer() && _history->peer()->id != peerId) { + clearBotStartToken(_history->peer()); + } _history->showHistory(peerId, showAtMsgId); bool noPeer = (!_history->peer() || !_history->peer()->id), onlyDialogs = noPeer && Adaptive::OneColumn(); @@ -2063,11 +2094,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac _overview->rpcClear(); _overview = nullptr; } - clearBotStartToken(_peerInStack); - dlgUpdated(); - _peerInStack = 0; - _msgIdInStack = 0; - _stack.clear(); } if (onlyDialogs) { _topBar->hide(); @@ -2111,6 +2137,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac } _dialogs->update(); } + topBar()->showAll(); App::wnd()->getTitle()->updateBackButton(); } @@ -2167,6 +2194,21 @@ bool MainWidget::mediaTypeSwitch() { return true; } +void MainWidget::saveSectionInStack() { + if (_overview) { + _stack.push_back(std_::make_unique(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); + } else if (_wideSection) { + _stack.push_back(std_::make_unique(_wideSection->createMemento())); + } else if (_history->peer()) { + dlgUpdated(); + _peerInStack = _history->peer(); + _msgIdInStack = _history->msgId(); + dlgUpdated(); + + _stack.push_back(std_::make_unique(_peerInStack, _msgIdInStack, _history->replyReturns())); + } +} + void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool back, int32 lastScrollTop) { if (peer->migrateTo()) { peer = peer->migrateTo(); @@ -2187,17 +2229,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool animationParams = prepareOverviewAnimation(); } if (!back) { - if (_overview) { - _stack.push_back(new StackItemOverview(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); - } else if (_wideSection) { - _stack.push_back(new StackItemSection(_wideSection->createMemento())); - } else if (_history->peer()) { - dlgUpdated(); - _peerInStack = _history->peer(); - _msgIdInStack = _history->msgId(); - dlgUpdated(); - _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, _history->replyReturns())); - } + saveSectionInStack(); } if (_overview) { _overview->hide(); @@ -2222,7 +2254,9 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool _overview->fastShow(); } _history->animStop(); - if (back) clearBotStartToken(_history->peer()); + if (back) { + clearBotStartToken(_history->peer()); + } _history->showHistory(0, 0); _history->hide(); if (Adaptive::OneColumn()) _dialogs->hide(); @@ -2238,17 +2272,7 @@ void MainWidget::showWideSection(const Window::SectionMemento &memento) { return; } - if (_overview) { - _stack.push_back(new StackItemOverview(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); - } else if (_wideSection) { - _stack.push_back(new StackItemSection(_wideSection->createMemento())); - } else if (_history->peer()) { - dlgUpdated(); - _peerInStack = _history->peer(); - _msgIdInStack = _history->msgId(); - dlgUpdated(); - _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, _history->replyReturns())); - } + saveSectionInStack(); showWideSectionAnimated(&memento, false); } @@ -2341,6 +2365,10 @@ void MainWidget::showWideSectionAnimated(const Window::SectionMemento *memento, App::wnd()->getTitle()->updateBackButton(); } +bool MainWidget::stackIsEmpty() const { + return _stack.isEmpty(); +} + void MainWidget::showBackFromStack() { if (selectingPeer()) return; if (_stack.isEmpty()) { @@ -2348,34 +2376,33 @@ void MainWidget::showBackFromStack() { if (App::wnd()) QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus())); return; } - StackItem *item = _stack.back(); + auto item = std_::move(_stack.back()); _stack.pop_back(); if (auto currentHistoryPeer = _history->peer()) { clearBotStartToken(currentHistoryPeer); } if (item->type() == HistoryStackItem) { dlgUpdated(); - _peerInStack = 0; + _peerInStack = nullptr; _msgIdInStack = 0; for (int32 i = _stack.size(); i > 0;) { if (_stack.at(--i)->type() == HistoryStackItem) { - _peerInStack = static_cast(_stack.at(i))->peer; - _msgIdInStack = static_cast(_stack.at(i))->msgId; + _peerInStack = static_cast(_stack.at(i).get())->peer; + _msgIdInStack = static_cast(_stack.at(i).get())->msgId; dlgUpdated(); break; } } - StackItemHistory *histItem = static_cast(item); - Ui::showPeerHistory(histItem->peer->id, App::main()->activeMsgId(), true); + StackItemHistory *histItem = static_cast(item.get()); + Ui::showPeerHistory(histItem->peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Backward); _history->setReplyReturns(histItem->peer->id, histItem->replyReturns); } else if (item->type() == SectionStackItem) { - StackItemSection *sectionItem = static_cast(item); + StackItemSection *sectionItem = static_cast(item.get()); showWideSectionAnimated(sectionItem->memento(), true); } else if (item->type() == OverviewStackItem) { - StackItemOverview *overItem = static_cast(item); + StackItemOverview *overItem = static_cast(item.get()); showMediaOverview(overItem->peer, overItem->mediaType, true, overItem->lastScrollTop); } - delete item; } void MainWidget::orderWidgets() { @@ -3343,7 +3370,7 @@ void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QStr Ui::showLayer(new ContactsBox(peer->asUser())); } else if (peer->isUser() && peer->asUser()->botInfo) { // Always open bot chats, even from mention links. - Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId); + Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); } else { Ui::showPeerProfile(peer); } @@ -3358,7 +3385,7 @@ void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QStr _history->resizeEvent(0); } } - Ui::showPeerHistoryAsync(peer->id, msgId); + Ui::showPeerHistoryAsync(peer->id, msgId, Ui::ShowWay::Forward); } } else { MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, qMakePair(msgId, startToken)), rpcFail(&MainWidget::usernameResolveFail, username)); @@ -3425,7 +3452,7 @@ void MainWidget::usernameResolveDone(QPair msgIdAndStartToken, c Ui::showLayer(new ContactsBox(peer->asUser())); } else if (peer->isUser() && peer->asUser()->botInfo) { // Always open bot chats, even from mention links. - Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId); + Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId, Ui::ShowWay::Forward); } else { Ui::showPeerProfile(peer); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index c6e937e42..baae91478 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -108,27 +108,6 @@ public: int32 lastWidth, lastScrollTop; }; -class StackItems : public QVector { -public: - bool contains(PeerData *peer) const { - for (int32 i = 0, l = size(); i < l; ++i) { - if (at(i)->peer == peer) { - return true; - } - } - return false; - } - void clear() { - for (int32 i = 0, l = size(); i < l; ++i) { - delete at(i); - } - QVector::clear(); - } - ~StackItems() { - clear(); - } -}; - enum SilentNotifiesStatus { SilentNotifiesDontChange, SilentNotifiesSetSilent, @@ -224,6 +203,7 @@ public: bool mediaTypeSwitch(); void showWideSection(const Window::SectionMemento &memento); void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1); + bool stackIsEmpty() const; void showBackFromStack(); void orderWidgets(); QRect historyRect() const; @@ -404,7 +384,7 @@ public: void ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout); bool ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout); bool ui_isInlineItemBeingChosen(); - void ui_showPeerHistory(quint64 peer, qint32 msgId, bool back); + void ui_showPeerHistory(quint64 peer, qint32 msgId, Ui::ShowWay way); PeerData *ui_getPeerForMouseAction(); void notify_botCommandsChanged(UserData *bot); @@ -493,7 +473,7 @@ public slots: void onSharePhoneWithBot(PeerData *recipient); - void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId); + void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way); void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId); private slots: @@ -519,6 +499,8 @@ private: Window::SectionSlideParams prepareOverviewAnimation(); Window::SectionSlideParams prepareDialogsAnimation(); + void saveSectionInStack(); + bool _started = false; uint64 failedObjId = 0; @@ -598,7 +580,7 @@ private: ChildWidget _topBar; ConfirmBox *_forwardConfirm = nullptr; // for single column layout ChildWidget _hider = { nullptr }; - StackItems _stack; + std_::vector_of_moveable> _stack; PeerData *_peerInStack = nullptr; MsgId _msgIdInStack = 0; diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 777de9b15..aaa886675 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -507,6 +507,7 @@ documentAttributeSticker#3a556302 alt:string stickerset:InputStickerSet = Docume documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute; documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute; documentAttributeFilename#15590068 file_name:string = DocumentAttribute; +documentAttributeVersion#99cd09ab version:int = DocumentAttribute; messages.stickersNotModified#f1749a22 = messages.Stickers; messages.stickers#8a8ecd32 hash:string stickers:Vector = messages.Stickers; diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.cpp b/Telegram/SourceFiles/mtproto/scheme_auto.cpp index f22248eaa..9b4b655c1 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.cpp +++ b/Telegram/SourceFiles/mtproto/scheme_auto.cpp @@ -4018,6 +4018,19 @@ void _serialize_documentAttributeFilename(MTPStringLogger &to, int32 stage, int3 } } +void _serialize_documentAttributeVersion(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ documentAttributeVersion"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int+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_stickersNotModified(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) { to.add("{ messages_stickersNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); } @@ -8612,6 +8625,7 @@ namespace { _serializers.insert(mtpc_documentAttributeVideo, _serialize_documentAttributeVideo); _serializers.insert(mtpc_documentAttributeAudio, _serialize_documentAttributeAudio); _serializers.insert(mtpc_documentAttributeFilename, _serialize_documentAttributeFilename); + _serializers.insert(mtpc_documentAttributeVersion, _serialize_documentAttributeVersion); _serializers.insert(mtpc_messages_stickersNotModified, _serialize_messages_stickersNotModified); _serializers.insert(mtpc_messages_stickers, _serialize_messages_stickers); _serializers.insert(mtpc_stickerPack, _serialize_stickerPack); diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index 15b3d4942..0c0d69db2 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.h +++ b/Telegram/SourceFiles/mtproto/scheme_auto.h @@ -372,6 +372,7 @@ enum { mtpc_documentAttributeVideo = 0x5910cccb, mtpc_documentAttributeAudio = 0x9852f9c6, mtpc_documentAttributeFilename = 0x15590068, + mtpc_documentAttributeVersion = 0x99cd09ab, mtpc_messages_stickersNotModified = 0xf1749a22, mtpc_messages_stickers = 0x8a8ecd32, mtpc_stickerPack = 0x12b299d4, @@ -1138,6 +1139,7 @@ class MTPDdocumentAttributeSticker; class MTPDdocumentAttributeVideo; class MTPDdocumentAttributeAudio; class MTPDdocumentAttributeFilename; +class MTPDdocumentAttributeVersion; class MTPmessages_stickers; class MTPDmessages_stickers; @@ -6971,6 +6973,18 @@ public: return *(const MTPDdocumentAttributeFilename*)data; } + MTPDdocumentAttributeVersion &_documentAttributeVersion() { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_documentAttributeVersion) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeVersion); + split(); + return *(MTPDdocumentAttributeVersion*)data; + } + const MTPDdocumentAttributeVersion &c_documentAttributeVersion() const { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_documentAttributeVersion) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeVersion); + return *(const MTPDdocumentAttributeVersion*)data; + } + uint32 innerLength() const; mtpTypeId type() const; void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons); @@ -6985,6 +6999,7 @@ private: explicit MTPdocumentAttribute(MTPDdocumentAttributeVideo *_data); explicit MTPdocumentAttribute(MTPDdocumentAttributeAudio *_data); explicit MTPdocumentAttribute(MTPDdocumentAttributeFilename *_data); + explicit MTPdocumentAttribute(MTPDdocumentAttributeVersion *_data); friend class MTP::internal::TypeCreator; @@ -12818,6 +12833,16 @@ public: MTPstring vfile_name; }; +class MTPDdocumentAttributeVersion : public mtpDataImpl { +public: + MTPDdocumentAttributeVersion() { + } + MTPDdocumentAttributeVersion(MTPint _version) : vversion(_version) { + } + + MTPint vversion; +}; + class MTPDmessages_stickers : public mtpDataImpl { public: MTPDmessages_stickers() { @@ -23329,6 +23354,9 @@ public: inline static MTPdocumentAttribute new_documentAttributeFilename(const MTPstring &_file_name) { return MTPdocumentAttribute(new MTPDdocumentAttributeFilename(_file_name)); } + inline static MTPdocumentAttribute new_documentAttributeVersion(MTPint _version) { + return MTPdocumentAttribute(new MTPDdocumentAttributeVersion(_version)); + } inline static MTPmessages_stickers new_messages_stickersNotModified() { return MTPmessages_stickers(mtpc_messages_stickersNotModified); } @@ -31459,6 +31487,10 @@ inline uint32 MTPdocumentAttribute::innerLength() const { const MTPDdocumentAttributeFilename &v(c_documentAttributeFilename()); return v.vfile_name.innerLength(); } + case mtpc_documentAttributeVersion: { + const MTPDdocumentAttributeVersion &v(c_documentAttributeVersion()); + return v.vversion.innerLength(); + } } return 0; } @@ -31503,6 +31535,11 @@ inline void MTPdocumentAttribute::read(const mtpPrime *&from, const mtpPrime *en MTPDdocumentAttributeFilename &v(_documentAttributeFilename()); v.vfile_name.read(from, end); } break; + case mtpc_documentAttributeVersion: _type = cons; { + if (!data) setData(new MTPDdocumentAttributeVersion()); + MTPDdocumentAttributeVersion &v(_documentAttributeVersion()); + v.vversion.read(from, end); + } break; default: throw mtpErrorUnexpected(cons, "MTPdocumentAttribute"); } } @@ -31536,6 +31573,10 @@ inline void MTPdocumentAttribute::write(mtpBuffer &to) const { const MTPDdocumentAttributeFilename &v(c_documentAttributeFilename()); v.vfile_name.write(to); } break; + case mtpc_documentAttributeVersion: { + const MTPDdocumentAttributeVersion &v(c_documentAttributeVersion()); + v.vversion.write(to); + } break; } } inline MTPdocumentAttribute::MTPdocumentAttribute(mtpTypeId type) : mtpDataOwner(0), _type(type) { @@ -31546,6 +31587,7 @@ inline MTPdocumentAttribute::MTPdocumentAttribute(mtpTypeId type) : mtpDataOwner case mtpc_documentAttributeVideo: setData(new MTPDdocumentAttributeVideo()); break; case mtpc_documentAttributeAudio: setData(new MTPDdocumentAttributeAudio()); break; case mtpc_documentAttributeFilename: setData(new MTPDdocumentAttributeFilename()); break; + case mtpc_documentAttributeVersion: setData(new MTPDdocumentAttributeVersion()); break; default: throw mtpErrorBadTypeId(type, "MTPdocumentAttribute"); } } @@ -31559,6 +31601,8 @@ inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeAudio *_d } inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeFilename *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeFilename) { } +inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeVersion *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeVersion) { +} inline MTPdocumentAttribute MTP_documentAttributeImageSize(MTPint _w, MTPint _h) { return MTP::internal::TypeCreator::new_documentAttributeImageSize(_w, _h); } @@ -31578,6 +31622,9 @@ inline MTPdocumentAttribute MTP_documentAttributeAudio(const MTPflagsisHidden()) { - if (Adaptive::OneColumn()) { + if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { _info->setPeer(h); _info->show(); } else {