diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 9c2484f6d..36b5053d9 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -712,6 +712,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_stickers_return" = "Undo"; "lng_stickers_restore" = "Restore"; "lng_stickers_count" = "{count:Loading...|# sticker|# stickers}"; +"lng_stickers_masks_pack" = "This is a pack of mask stickers. You can use them in the photo editor on our mobile apps."; "lng_in_dlg_photo" = "Photo"; "lng_in_dlg_video" = "Video file"; @@ -875,8 +876,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_reply_cant_forward" = "Sorry, no way to reply to an old message in supergroup :( Do you wish to forward it and add your comment?"; "lng_share_title" = "Share to"; -"lng_share_confirm" = "Share"; +"lng_share_copy_link" = "Copy share link"; +"lng_share_confirm" = "Send"; "lng_share_wrong_user" = "This game was opened from a different user."; +"lng_share_game_link_copied" = "Game link copied to clipboard."; +"lng_share_done" = "Done!"; "lng_contact_phone" = "Phone number"; "lng_enter_contact_data" = "New Contact"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index a456e1856..999c47d82 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,6,0 - PRODUCTVERSION 0,10,6,0 + FILEVERSION 0,10,7,0 + PRODUCTVERSION 0,10,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.6.0" + VALUE "FileVersion", "0.10.7.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.6.0" + VALUE "ProductVersion", "0.10.7.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 34bd669ad..1db28bea8 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,6,0 - PRODUCTVERSION 0,10,6,0 + FILEVERSION 0,10,7,0 + PRODUCTVERSION 0,10,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.10.6.0" + VALUE "FileVersion", "0.10.7.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.6.0" + VALUE "ProductVersion", "0.10.7.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/boxes/sharebox.cpp b/Telegram/SourceFiles/boxes/sharebox.cpp index fdeba32c8..37084e249 100644 --- a/Telegram/SourceFiles/boxes/sharebox.cpp +++ b/Telegram/SourceFiles/boxes/sharebox.cpp @@ -31,12 +31,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" #include "boxes/confirmbox.h" #include "apiwrap.h" +#include "ui/toast/toast.h" -ShareBox::ShareBox(SubmitCallback &&callback) : ItemListBox(st::boxScroll) -, _callback(std_::move(callback)) +ShareBox::ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback) : ItemListBox(st::boxScroll) +, _copyCallback(std_::move(copyCallback)) +, _submitCallback(std_::move(submitCallback)) , _inner(this) , _filter(this, st::boxSearchField, lang(lng_participant_filter)) , _filterCancel(this, st::boxSearchCancel) +, _copy(this, lang(lng_share_copy_link), st::defaultBoxButton) , _share(this, lang(lng_share_confirm), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _topShadow(this) @@ -47,7 +50,8 @@ ShareBox::ShareBox(SubmitCallback &&callback) : ItemListBox(st::boxScroll) connect(_inner, SIGNAL(selectedChanged()), this, SLOT(onSelectedChanged())); connect(_inner, SIGNAL(mustScrollTo(int,int)), this, SLOT(onMustScrollTo(int,int))); - connect(_share, SIGNAL(clicked()), this, SLOT(onShare())); + connect(_copy, SIGNAL(clicked()), this, SLOT(onCopyLink())); + connect(_share, SIGNAL(clicked()), this, SLOT(onSubmit())); connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose())); connect(scrollArea(), SIGNAL(scrolled()), this, SLOT(onScroll())); connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); @@ -61,6 +65,8 @@ ShareBox::ShareBox(SubmitCallback &&callback) : ItemListBox(st::boxScroll) _searchTimer.setSingleShot(true); connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchByUsername())); + updateButtonsVisibility(); + prepare(); } @@ -173,12 +179,16 @@ void ShareBox::keyPressEvent(QKeyEvent *e) { } void ShareBox::moveButtons() { + _copy->moveToRight(st::boxButtonPadding.right(), _share->y()); _share->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _share->height()); - auto cancelRight = st::boxButtonPadding.right(); - if (_inner->hasSelected()) { - cancelRight += _share->width() + st::boxButtonPadding.left(); - } - _cancel->moveToRight(cancelRight, _share->y()); + _cancel->moveToRight(st::boxButtonPadding.right() + _share->width() + st::boxButtonPadding.left(), _share->y()); +} + +void ShareBox::updateButtonsVisibility() { + auto hasSelected = _inner->hasSelected(); + _copy->setVisible(!hasSelected); + _share->setVisible(hasSelected); + _cancel->setVisible(hasSelected); } void ShareBox::onFilterCancel() { @@ -190,14 +200,20 @@ void ShareBox::onFilterUpdate() { _inner->updateFilter(_filter->getLastText()); } -void ShareBox::onShare() { - if (_callback) { - _callback(_inner->selected()); +void ShareBox::onSubmit() { + if (_submitCallback) { + _submitCallback(_inner->selected()); + } +} + +void ShareBox::onCopyLink() { + if (_copyCallback) { + _copyCallback(); } } void ShareBox::onSelectedChanged() { - _share->setVisible(_inner->hasSelected()); + updateButtonsVisibility(); moveButtons(); update(); } @@ -928,19 +944,76 @@ QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) { namespace { void shareGameScoreFromItem(HistoryItem *item) { - Ui::showLayer(new ShareBox([msgId = item->fullId()](const QVector &result) { - MTPmessages_ForwardMessages::Flags sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score; - MTPVector msgIds = MTP_vector(1, MTP_int(msgId.msg)); + struct ShareGameScoreData { + ShareGameScoreData(const FullMsgId &msgId) : msgId(msgId) { + } + FullMsgId msgId; + OrderedSet requests; + }; + auto data = MakeShared(item->fullId()); + + auto copyCallback = [data]() { if (auto main = App::main()) { - if (auto item = App::histItemById(msgId)) { - for_const (auto peer, result) { - MTPVector random = MTP_vector(1, rand_value()); - MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input), main->rpcDone(&MainWidget::sentUpdatesReceived)); + if (auto item = App::histItemById(data->msgId)) { + if (auto bot = item->getMessageBot()) { + if (auto markup = item->Get()) { + for (int i = 0, rowsCount = markup->rows.size(); i != rowsCount; ++i) { + auto &row = markup->rows[i]; + for (int j = 0, buttonsCount = row.size(); j != buttonsCount; ++j) { + auto &button = row[j]; + if (button.type == HistoryMessageReplyMarkup::Button::Type::Game) { + auto strData = QString::fromUtf8(button.data); + auto parts = strData.split(','); + t_assert(parts.size() > 1); + + QApplication::clipboard()->setText(qsl("https://telegram.me/") + bot->username + qsl("?start=") + parts[1]); + + Ui::Toast::Config toast; + toast.text = lang(lng_share_game_link_copied); + Ui::Toast::Show(App::wnd(), toast); + return; + } + } + } + } } } } - Ui::hideLayer(); - })); + }; + auto submitCallback = [data](const QVector &result) { + if (!data->requests.empty()) { + return; // Share clicked already. + } + + auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) { + if (auto main = App::main()) { + main->sentUpdatesReceived(updates); + } + data->requests.remove(requestId); + if (data->requests.empty()) { + Ui::Toast::Config toast; + toast.text = lang(lng_share_done); + Ui::Toast::Show(App::wnd(), toast); + + Ui::hideLayer(); + } + }; + + MTPmessages_ForwardMessages::Flags sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score; + MTPVector msgIds = MTP_vector(1, MTP_int(data->msgId.msg)); + if (auto main = App::main()) { + if (auto item = App::histItemById(data->msgId)) { + for_const (auto peer, result) { + MTPVector random = MTP_vector(1, rand_value()); + auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input); + auto callback = doneCallback; + auto requestId = MTP::send(request, rpcDone(std_::move(callback))); + data->requests.insert(requestId); + } + } + } + }; + Ui::showLayer(new ShareBox(std_::move(copyCallback), std_::move(submitCallback))); } class GameMessageResolvedCallback : public SharedCallback { diff --git a/Telegram/SourceFiles/boxes/sharebox.h b/Telegram/SourceFiles/boxes/sharebox.h index cff80d344..696a28242 100644 --- a/Telegram/SourceFiles/boxes/sharebox.h +++ b/Telegram/SourceFiles/boxes/sharebox.h @@ -44,8 +44,9 @@ class ShareBox : public ItemListBox, public RPCSender { Q_OBJECT public: + using CopyCallback = base::lambda_unique; using SubmitCallback = base::lambda_unique &)>; - ShareBox(SubmitCallback &&callback); + ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback); private slots: void onFilterUpdate(); @@ -55,7 +56,8 @@ private slots: bool onSearchByUsername(bool searchCache = false); void onNeedSearchByUsername(); - void onShare(); + void onSubmit(); + void onCopyLink(); void onSelectedChanged(); void onMustScrollTo(int top, int bottom); @@ -69,16 +71,19 @@ protected: private: void moveButtons(); + void updateButtonsVisibility(); void peopleReceived(const MTPcontacts_Found &result, mtpRequestId requestId); bool peopleFailed(const RPCError &error, mtpRequestId requestId); - SubmitCallback _callback; + CopyCallback _copyCallback; + SubmitCallback _submitCallback; ChildWidget _inner; ChildWidget _filter; ChildWidget _filterCancel; + ChildWidget _copy; ChildWidget _share; ChildWidget _cancel; diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index c7e46a291..0f9974954 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -234,6 +234,9 @@ void StickerSetInner::mouseReleaseEvent(QMouseEvent *e) { void StickerSetInner::updateSelected() { auto index = stickerFromGlobalPos(QCursor::pos()); + if (isMasksSet()) { + index = -1; + } if (index != _selected) { startOverAnimation(_selected, 1., 0.); _selected = index; @@ -356,6 +359,10 @@ QString StickerSetInner::shortName() const { } void StickerSetInner::install() { + if (isMasksSet()) { + Ui::showLayer(new InformBox(lang(lng_stickers_masks_pack)), KeepOtherLayers); + return; + } if (_installRequest) return; _installRequest = MTP::send(MTPmessages_InstallStickerSet(_input, MTP_bool(false)), rpcDone(&StickerSetInner::installDone), rpcFail(&StickerSetInner::installFail)); } @@ -1328,11 +1335,13 @@ void StickersBox::setup() { if (_section == Section::Installed) { Local::readArchivedStickers(); if (Global::ArchivedStickerSetsOrder().isEmpty()) { - _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_long(0), MTP_int(kArchivedLimitFirstRequest)), rpcDone(&StickersBox::getArchivedDone, 0ULL)); + MTPmessages_GetArchivedStickers::Flags flags = 0; + _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(flags), MTP_long(0), MTP_int(kArchivedLimitFirstRequest)), rpcDone(&StickersBox::getArchivedDone, 0ULL)); } } else if (_section == Section::Archived) { // Reload the archived list. - _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_long(0), MTP_int(kArchivedLimitFirstRequest)), rpcDone(&StickersBox::getArchivedDone, 0ULL)); + MTPmessages_GetArchivedStickers::Flags flags = 0; + _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(flags), MTP_long(0), MTP_int(kArchivedLimitFirstRequest)), rpcDone(&StickersBox::getArchivedDone, 0ULL)); auto &sets = Global::StickerSets(); for_const (auto setId, Global::ArchivedStickerSetsOrder()) { @@ -1414,7 +1423,8 @@ void StickersBox::checkLoadMoreArchived() { } } } - _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_long(lastId), MTP_int(kArchivedLimitPerPage)), rpcDone(&StickersBox::getArchivedDone, lastId)); + MTPmessages_GetArchivedStickers::Flags flags = 0; + _archivedRequestId = MTP::send(MTPmessages_GetArchivedStickers(MTP_flags(flags), MTP_long(lastId), MTP_int(kArchivedLimitPerPage)), rpcDone(&StickersBox::getArchivedDone, lastId)); } } } diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index d5c4d2f81..699780a97 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.h +++ b/Telegram/SourceFiles/boxes/stickersetbox.h @@ -65,6 +65,10 @@ private: void installDone(const MTPmessages_StickerSetInstallResult &result); bool installFail(const RPCError &error); + bool isMasksSet() const { + return (_setFlags & MTPDstickerSet::Flag::f_masks); + } + QVector _packOvers; StickerPack _pack; StickersByEmojiMap _emoji; diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index 1c55c648d..36b25a67a 100644 --- a/Telegram/SourceFiles/core/click_handler_types.cpp +++ b/Telegram/SourceFiles/core/click_handler_types.cpp @@ -103,9 +103,7 @@ TextWithEntities UrlClickHandler::getExpandedLinkTextWithEntities(ExpandLinksMod } void HiddenUrlClickHandler::onClick(Qt::MouseButton button) const { - auto u = url(); - - u = tryConvertUrlToLocal(u); + auto u = tryConvertUrlToLocal(url()); if (u.startsWith(qstr("tg://"))) { App::openLocalUrl(u); @@ -115,9 +113,7 @@ void HiddenUrlClickHandler::onClick(Qt::MouseButton button) const { } void BotGameUrlClickHandler::onClick(Qt::MouseButton button) const { - auto u = url(); - - u = tryConvertUrlToLocal(u); + auto u = tryConvertUrlToLocal(url()); if (u.startsWith(qstr("tg://"))) { App::openLocalUrl(u); diff --git a/Telegram/SourceFiles/core/click_handler_types.h b/Telegram/SourceFiles/core/click_handler_types.h index a64a16849..d8231da31 100644 --- a/Telegram/SourceFiles/core/click_handler_types.h +++ b/Telegram/SourceFiles/core/click_handler_types.h @@ -29,7 +29,7 @@ public: } void copyToClipboard() const override { - QString u = url(); + auto u = url(); if (!u.isEmpty()) { QApplication::clipboard()->setText(u); } diff --git a/Telegram/SourceFiles/core/lambda_wrap.h b/Telegram/SourceFiles/core/lambda_wrap.h index 765c71859..344e839f4 100644 --- a/Telegram/SourceFiles/core/lambda_wrap.h +++ b/Telegram/SourceFiles/core/lambda_wrap.h @@ -403,11 +403,188 @@ private: }; template -inline Function lambda_wrap_helper(base::lambda_unique &&lambda) { +inline Function func_lambda_wrap_helper(base::lambda_unique &&lambda) { return Function(new LambdaFunctionImplementation(std_::move(lambda))); } template ::value>> inline LambdaGetFunction func(Lambda &&lambda) { - return lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); + return func_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); +} + +// While we still use rpcDone() and rpcFail() + +#include "mtproto/rpc_sender.h" + +template +class RPCHandlerImplementation : public Base { +protected: + using Lambda = base::lambda_unique; + using Parent = RPCHandlerImplementation; + +public: + RPCHandlerImplementation(Lambda &&handler) : _handler(std_::move(handler)) { + } + +protected: + Lambda _handler; + +}; + +template +using RPCDoneHandlerImplementation = RPCHandlerImplementation; + +template +class RPCDoneHandlerImplementationBare : public RPCDoneHandlerImplementation { // done(from, end) +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(from, end) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationBareReq : public RPCDoneHandlerImplementation { // done(from, end, req_id) +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(from, end, requestId) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationPlain : public RPCDoneHandlerImplementation { // done(result) +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(T(from, end)) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationReq : public RPCDoneHandlerImplementation { // done(result, req_id) +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(T(from, end), requestId) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationNo : public RPCDoneHandlerImplementation { // done() +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler() : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationNoReq : public RPCDoneHandlerImplementation { // done(req_id) +public: + using Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(requestId) : void(0); + } + +}; + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBare(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBareReq(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationPlain(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationReq(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNo(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNoReq(std_::move(lambda))); +} + +template ::value>> +RPCDoneHandlerPtr rpcDone(Lambda &&lambda) { + return rpcDone_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); +} + +template +using RPCFailHandlerImplementation = RPCHandlerImplementation; + +class RPCFailHandlerImplementationPlain : public RPCFailHandlerImplementation { // fail(error) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return _handler ? _handler(error) : true; + } + +}; + +class RPCFailHandlerImplementationReq : public RPCFailHandlerImplementation { // fail(error, req_id) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler(error, requestId) : true; + } + +}; + +class RPCFailHandlerImplementationNo : public RPCFailHandlerImplementation { // fail() +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler() : true; + } + +}; + +class RPCFailHandlerImplementationNoReq : public RPCFailHandlerImplementation { // fail(req_id) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler(requestId) : true; + } + +}; + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationPlain(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationReq(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationNo(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationNoReq(std_::move(lambda))); +} + +template ::value>> +RPCFailHandlerPtr rpcFail(Lambda &&lambda) { + return rpcFail_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); } diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 1e2acd471..2153f12b9 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10006; -constexpr str_const AppVersionStr = "0.10.6"; +constexpr int AppVersion = 10007; +constexpr str_const AppVersionStr = "0.10.7"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 41a4ab839..69f133c6a 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -97,17 +97,7 @@ void activateBotCommand(const HistoryItem *msg, int row, int col) { case ButtonType::SwitchInlineSame: case ButtonType::SwitchInline: { if (auto m = App::main()) { - auto getMessageBot = [msg]() -> UserData* { - if (auto bot = msg->viaBot()) { - return bot; - } else if (auto bot = msg->from()->asUser()) { - return bot; - } else if (auto bot = msg->history()->peer->asUser()) { - return bot; - } - return nullptr; - }; - if (auto bot = getMessageBot()) { + if (auto bot = msg->getMessageBot()) { auto tryFastSwitch = [bot, &button, msgId = msg->id]() -> bool { auto samePeer = (button->type == ButtonType::SwitchInlineSame); if (samePeer) { diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index df5e715af..bb4422dac 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -2581,7 +2581,17 @@ void HistoryMessageReplyMarkup::createFromButtonRows(const QVector= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '_') || (ch == '-'); + }; + for (auto &ch : start) { + if (!charIsGoodForStartParam(ch)) { + ch = '_'; + } + } + auto strData = QString::number(buttonData.vgame_id.v) + ',' + start + ',' + title; buttonRow.push_back({ Button::Type::Game, qs(buttonData.vtext), strData.toUtf8(), 0 }); } break; } @@ -6468,7 +6478,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) { replyToLnk.reset(new GoToMessageClickHandler(replyToMsg->history()->peer->id, replyToMsg->id)); if (!replyToMsg->Has()) { - if (UserData *bot = replyToMsg->viaBot()) { + if (auto bot = replyToMsg->viaBot()) { _replyToVia.reset(new HistoryMessageVia()); _replyToVia->create(peerToUser(bot->id)); } @@ -6720,7 +6730,7 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl if (fwd->authorOriginal()->isChannel()) { config.originalId = fwd->id; } - UserData *fwdViaBot = fwd->viaBot(); + auto fwdViaBot = fwd->viaBot(); if (fwdViaBot) config.viaBotId = peerToUser(fwdViaBot->id); int fwdViewsCount = fwd->viewsCount(); if (fwdViewsCount > 0) { @@ -8133,7 +8143,9 @@ bool HistoryService::prepareGameScoreText(const QString &from, QString *outText, if (button.type == HistoryMessageReplyMarkup::Button::Type::Game) { auto strData = QString::fromUtf8(button.data); second = MakeShared(item, i, j); - return textcmdLink(2, strData.mid(strData.indexOf(',') + 1)); + auto parts = strData.split(','); + t_assert(parts.size() > 2); + return textcmdLink(2, parts.mid(2).join(',')); } } } diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 9773f0219..d8435ab2d 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -1061,6 +1061,16 @@ public: } return nullptr; } + UserData *getMessageBot() const { + if (auto bot = viaBot()) { + return bot; + } + auto bot = from()->asUser(); + if (!bot) { + bot = history()->peer->asUser(); + } + return (bot && bot->botInfo) ? bot : nullptr; + }; History *history() const { return _history; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 8d27947f3..ccf5631df 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3874,7 +3874,7 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic if (set) { auto it = sets.find(set->vid.v); - QString title = stickerSetTitle(*set); + auto title = stickerSetTitle(*set); if (it == sets.cend()) { auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded; if (unread.contains(set->vid.v)) { @@ -5783,13 +5783,7 @@ void HistoryWidget::app_sendBotCallback(const HistoryMessageReplyMarkup::Button bool lastKeyboardUsed = (_keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)) && (_keyboard.forMsgId() == FullMsgId(_channel, msg->id)); - auto bot = msg->viaBot(); - if (!bot) { - bot = msg->from()->asUser(); - if (bot && !bot->botInfo) { - bot = nullptr; - } - } + auto bot = msg->getMessageBot(); using ButtonType = HistoryMessageReplyMarkup::Button::Type; BotCallbackInfo info = { bot, msg->fullId(), row, col, (button->type == ButtonType::Game) }; diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 843bbf991..ba2100cb3 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -387,9 +387,9 @@ updateBotInlineQuery#54826690 flags:# query_id:long user_id:int query:string geo updateBotInlineSend#e48f964 flags:# user_id:int query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update; updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update; updateChannelPinnedMessage#98592475 channel_id:int id:int = Update; -updateBotCallbackQuery#81c5615f flags:# query_id:long user_id:int peer:Peer msg_id:int data:flags.0?bytes game_id:flags.1?int = Update; +updateBotCallbackQuery#4bf9a8a0 flags:# query_id:long user_id:int peer:Peer msg_id:int chat_instance:long data:flags.0?bytes game_id:flags.1?int = Update; updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update; -updateInlineBotCallbackQuery#d618a28b flags:# query_id:long user_id:int msg_id:InputBotInlineMessageID data:flags.0?bytes game_id:flags.1?int = Update; +updateInlineBotCallbackQuery#4f2f45d1 flags:# query_id:long user_id:int msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_id:flags.1?int = Update; updateReadChannelOutbox#25d6c9c7 channel_id:int max_id:int = Update; updateDraftMessage#ee2bb969 peer:Peer draft:DraftMessage = Update; updateReadFeaturedStickers#571d2742 = Update; @@ -861,7 +861,7 @@ messages.readFeaturedStickers#5b118126 id:Vector = Bool; messages.getRecentStickers#5ea192c9 flags:# attached:flags.0?true hash:int = messages.RecentStickers; messages.saveRecentSticker#392718f8 flags:# attached:flags.0?true id:InputDocument unsave:Bool = Bool; messages.clearRecentStickers#8999602d flags:# attached:flags.0?true = Bool; -messages.getArchivedStickers#906e241f offset_id:long limit:int = messages.ArchivedStickers; +messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true offset_id:long limit:int = messages.ArchivedStickers; messages.setGameScore#dfbc7c1f flags:# edit_message:flags.0?true peer:InputPeer id:int user_id:InputUser game_id:int score:int = Updates; messages.setInlineGameScore#54f882f1 flags:# edit_message:flags.0?true id:InputBotInlineMessageID user_id:InputUser game_id:int score:int = Bool; messages.getMaskStickers#65b8c79f hash:int = messages.AllStickers; diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.cpp b/Telegram/SourceFiles/mtproto/scheme_auto.cpp index 99d2c3491..58618e4b8 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.cpp +++ b/Telegram/SourceFiles/mtproto/scheme_auto.cpp @@ -2997,8 +2997,9 @@ void _serialize_updateBotCallbackQuery(MTPStringLogger &to, int32 stage, int32 l case 2: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); 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(" msg_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" data: "); ++stages.back(); if (flag & MTPDupdateBotCallbackQuery::Flag::f_data) { types.push_back(mtpc_bytes+0); 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(" game_id: "); ++stages.back(); if (flag & MTPDupdateBotCallbackQuery::Flag::f_game_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; + case 5: to.add(" chat_instance: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" data: "); ++stages.back(); if (flag & MTPDupdateBotCallbackQuery::Flag::f_data) { types.push_back(mtpc_bytes+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; + case 7: to.add(" game_id: "); ++stages.back(); if (flag & MTPDupdateBotCallbackQuery::Flag::f_game_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -3032,8 +3033,9 @@ void _serialize_updateInlineBotCallbackQuery(MTPStringLogger &to, int32 stage, i case 1: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 2: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 3: to.add(" msg_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" data: "); ++stages.back(); if (flag & MTPDupdateInlineBotCallbackQuery::Flag::f_data) { types.push_back(mtpc_bytes+0); 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(" game_id: "); ++stages.back(); if (flag & MTPDupdateInlineBotCallbackQuery::Flag::f_game_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; + case 4: to.add(" chat_instance: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" data: "); ++stages.back(); if (flag & MTPDupdateInlineBotCallbackQuery::Flag::f_data) { types.push_back(mtpc_bytes+0); 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(" game_id: "); ++stages.back(); if (flag & MTPDupdateInlineBotCallbackQuery::Flag::f_game_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -8437,6 +8439,8 @@ void _serialize_messages_getRecentStickers(MTPStringLogger &to, int32 stage, int } void _serialize_messages_getArchivedStickers(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) { + MTPmessages_getArchivedStickers::Flags flag(iflag); + if (stage) { to.add(",\n").addSpaces(lev); } else { @@ -8444,8 +8448,10 @@ void _serialize_messages_getArchivedStickers(MTPStringLogger &to, int32 stage, i to.add("\n").addSpaces(lev); } switch (stage) { - case 0: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" masks: "); ++stages.back(); if (flag & MTPmessages_getArchivedStickers::Flag::f_masks) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; + case 2: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" limit: "); ++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; } } diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index 393e133ec..9f9813388 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.h +++ b/Telegram/SourceFiles/mtproto/scheme_auto.h @@ -284,9 +284,9 @@ enum { mtpc_updateBotInlineSend = 0xe48f964, mtpc_updateEditChannelMessage = 0x1b3f4df7, mtpc_updateChannelPinnedMessage = 0x98592475, - mtpc_updateBotCallbackQuery = 0x81c5615f, + mtpc_updateBotCallbackQuery = 0x4bf9a8a0, mtpc_updateEditMessage = 0xe40370a3, - mtpc_updateInlineBotCallbackQuery = 0xd618a28b, + mtpc_updateInlineBotCallbackQuery = 0x4f2f45d1, mtpc_updateReadChannelOutbox = 0x25d6c9c7, mtpc_updateDraftMessage = 0xee2bb969, mtpc_updateReadFeaturedStickers = 0x571d2742, @@ -653,7 +653,7 @@ enum { mtpc_messages_getRecentStickers = 0x5ea192c9, mtpc_messages_saveRecentSticker = 0x392718f8, mtpc_messages_clearRecentStickers = 0x8999602d, - mtpc_messages_getArchivedStickers = 0x906e241f, + mtpc_messages_getArchivedStickers = 0x57f17692, mtpc_messages_setGameScore = 0xdfbc7c1f, mtpc_messages_setInlineGameScore = 0x54f882f1, mtpc_messages_getMaskStickers = 0x65b8c79f, @@ -12365,7 +12365,7 @@ public: MTPDupdateBotCallbackQuery() { } - MTPDupdateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPbytes &_data, MTPint _game_id) : vflags(_flags), vquery_id(_query_id), vuser_id(_user_id), vpeer(_peer), vmsg_id(_msg_id), vdata(_data), vgame_id(_game_id) { + MTPDupdateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) : vflags(_flags), vquery_id(_query_id), vuser_id(_user_id), vpeer(_peer), vmsg_id(_msg_id), vchat_instance(_chat_instance), vdata(_data), vgame_id(_game_id) { } MTPflags vflags; @@ -12373,6 +12373,7 @@ public: MTPint vuser_id; MTPPeer vpeer; MTPint vmsg_id; + MTPlong vchat_instance; MTPbytes vdata; MTPint vgame_id; }; @@ -12405,13 +12406,14 @@ public: MTPDupdateInlineBotCallbackQuery() { } - MTPDupdateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPbytes &_data, MTPint _game_id) : vflags(_flags), vquery_id(_query_id), vuser_id(_user_id), vmsg_id(_msg_id), vdata(_data), vgame_id(_game_id) { + MTPDupdateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) : vflags(_flags), vquery_id(_query_id), vuser_id(_user_id), vmsg_id(_msg_id), vchat_instance(_chat_instance), vdata(_data), vgame_id(_game_id) { } MTPflags vflags; MTPlong vquery_id; MTPint vuser_id; MTPInputBotInlineMessageID vmsg_id; + MTPlong vchat_instance; MTPbytes vdata; MTPint vgame_id; }; @@ -21347,6 +21349,16 @@ public: class MTPmessages_getArchivedStickers { // RPC method 'messages.getArchivedStickers' public: + enum class Flag : int32 { + f_masks = (1 << 0), + MAX_FIELD = (1 << 0), + }; + Q_DECLARE_FLAGS(Flags, Flag); + friend inline Flags operator~(Flag v) { return QFlag(~static_cast(v)); } + + bool is_masks() const { return vflags.v & Flag::f_masks; } + + MTPflags vflags; MTPlong voffset_id; MTPint vlimit; @@ -21355,26 +21367,30 @@ public: MTPmessages_getArchivedStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getArchivedStickers) { read(from, end, cons); } - MTPmessages_getArchivedStickers(const MTPlong &_offset_id, MTPint _limit) : voffset_id(_offset_id), vlimit(_limit) { + MTPmessages_getArchivedStickers(const MTPflags &_flags, const MTPlong &_offset_id, MTPint _limit) : vflags(_flags), voffset_id(_offset_id), vlimit(_limit) { } uint32 innerLength() const { - return voffset_id.innerLength() + vlimit.innerLength(); + return vflags.innerLength() + voffset_id.innerLength() + vlimit.innerLength(); } mtpTypeId type() const { return mtpc_messages_getArchivedStickers; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getArchivedStickers) { + vflags.read(from, end); voffset_id.read(from, end); vlimit.read(from, end); } void write(mtpBuffer &to) const { + vflags.write(to); voffset_id.write(to); vlimit.write(to); } typedef MTPmessages_ArchivedStickers ResponseType; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(MTPmessages_getArchivedStickers::Flags) + class MTPmessages_GetArchivedStickers : public MTPBoxed { public: MTPmessages_GetArchivedStickers() { @@ -21383,7 +21399,7 @@ public: } MTPmessages_GetArchivedStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_GetArchivedStickers(const MTPlong &_offset_id, MTPint _limit) : MTPBoxed(MTPmessages_getArchivedStickers(_offset_id, _limit)) { + MTPmessages_GetArchivedStickers(const MTPflags &_flags, const MTPlong &_offset_id, MTPint _limit) : MTPBoxed(MTPmessages_getArchivedStickers(_flags, _offset_id, _limit)) { } }; @@ -24140,14 +24156,14 @@ public: inline static MTPupdate new_updateChannelPinnedMessage(MTPint _channel_id, MTPint _id) { return MTPupdate(new MTPDupdateChannelPinnedMessage(_channel_id, _id)); } - inline static MTPupdate new_updateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPbytes &_data, MTPint _game_id) { - return MTPupdate(new MTPDupdateBotCallbackQuery(_flags, _query_id, _user_id, _peer, _msg_id, _data, _game_id)); + inline static MTPupdate new_updateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) { + return MTPupdate(new MTPDupdateBotCallbackQuery(_flags, _query_id, _user_id, _peer, _msg_id, _chat_instance, _data, _game_id)); } inline static MTPupdate new_updateEditMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) { return MTPupdate(new MTPDupdateEditMessage(_message, _pts, _pts_count)); } - inline static MTPupdate new_updateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPbytes &_data, MTPint _game_id) { - return MTPupdate(new MTPDupdateInlineBotCallbackQuery(_flags, _query_id, _user_id, _msg_id, _data, _game_id)); + inline static MTPupdate new_updateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) { + return MTPupdate(new MTPDupdateInlineBotCallbackQuery(_flags, _query_id, _user_id, _msg_id, _chat_instance, _data, _game_id)); } inline static MTPupdate new_updateReadChannelOutbox(MTPint _channel_id, MTPint _max_id) { return MTPupdate(new MTPDupdateReadChannelOutbox(_channel_id, _max_id)); @@ -29744,7 +29760,7 @@ inline uint32 MTPupdate::innerLength() const { } case mtpc_updateBotCallbackQuery: { const MTPDupdateBotCallbackQuery &v(c_updateBotCallbackQuery()); - return v.vflags.innerLength() + v.vquery_id.innerLength() + v.vuser_id.innerLength() + v.vpeer.innerLength() + v.vmsg_id.innerLength() + (v.has_data() ? v.vdata.innerLength() : 0) + (v.has_game_id() ? v.vgame_id.innerLength() : 0); + return v.vflags.innerLength() + v.vquery_id.innerLength() + v.vuser_id.innerLength() + v.vpeer.innerLength() + v.vmsg_id.innerLength() + v.vchat_instance.innerLength() + (v.has_data() ? v.vdata.innerLength() : 0) + (v.has_game_id() ? v.vgame_id.innerLength() : 0); } case mtpc_updateEditMessage: { const MTPDupdateEditMessage &v(c_updateEditMessage()); @@ -29752,7 +29768,7 @@ inline uint32 MTPupdate::innerLength() const { } case mtpc_updateInlineBotCallbackQuery: { const MTPDupdateInlineBotCallbackQuery &v(c_updateInlineBotCallbackQuery()); - return v.vflags.innerLength() + v.vquery_id.innerLength() + v.vuser_id.innerLength() + v.vmsg_id.innerLength() + (v.has_data() ? v.vdata.innerLength() : 0) + (v.has_game_id() ? v.vgame_id.innerLength() : 0); + return v.vflags.innerLength() + v.vquery_id.innerLength() + v.vuser_id.innerLength() + v.vmsg_id.innerLength() + v.vchat_instance.innerLength() + (v.has_data() ? v.vdata.innerLength() : 0) + (v.has_game_id() ? v.vgame_id.innerLength() : 0); } case mtpc_updateReadChannelOutbox: { const MTPDupdateReadChannelOutbox &v(c_updateReadChannelOutbox()); @@ -30069,6 +30085,7 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI v.vuser_id.read(from, end); v.vpeer.read(from, end); v.vmsg_id.read(from, end); + v.vchat_instance.read(from, end); if (v.has_data()) { v.vdata.read(from, end); } else { v.vdata = MTPbytes(); } if (v.has_game_id()) { v.vgame_id.read(from, end); } else { v.vgame_id = MTPint(); } } break; @@ -30086,6 +30103,7 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI v.vquery_id.read(from, end); v.vuser_id.read(from, end); v.vmsg_id.read(from, end); + v.vchat_instance.read(from, end); if (v.has_data()) { v.vdata.read(from, end); } else { v.vdata = MTPbytes(); } if (v.has_game_id()) { v.vgame_id.read(from, end); } else { v.vgame_id = MTPint(); } } break; @@ -30362,6 +30380,7 @@ inline void MTPupdate::write(mtpBuffer &to) const { v.vuser_id.write(to); v.vpeer.write(to); v.vmsg_id.write(to); + v.vchat_instance.write(to); if (v.has_data()) v.vdata.write(to); if (v.has_game_id()) v.vgame_id.write(to); } break; @@ -30377,6 +30396,7 @@ inline void MTPupdate::write(mtpBuffer &to) const { v.vquery_id.write(to); v.vuser_id.write(to); v.vmsg_id.write(to); + v.vchat_instance.write(to); if (v.has_data()) v.vdata.write(to); if (v.has_game_id()) v.vgame_id.write(to); } break; @@ -30681,15 +30701,15 @@ inline MTPupdate MTP_updateChannelPinnedMessage(MTPint _channel_id, MTPint _id) return MTP::internal::TypeCreator::new_updateChannelPinnedMessage(_channel_id, _id); } Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDupdateBotCallbackQuery::Flags) -inline MTPupdate MTP_updateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPbytes &_data, MTPint _game_id) { - return MTP::internal::TypeCreator::new_updateBotCallbackQuery(_flags, _query_id, _user_id, _peer, _msg_id, _data, _game_id); +inline MTPupdate MTP_updateBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPPeer &_peer, MTPint _msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) { + return MTP::internal::TypeCreator::new_updateBotCallbackQuery(_flags, _query_id, _user_id, _peer, _msg_id, _chat_instance, _data, _game_id); } inline MTPupdate MTP_updateEditMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) { return MTP::internal::TypeCreator::new_updateEditMessage(_message, _pts, _pts_count); } Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDupdateInlineBotCallbackQuery::Flags) -inline MTPupdate MTP_updateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPbytes &_data, MTPint _game_id) { - return MTP::internal::TypeCreator::new_updateInlineBotCallbackQuery(_flags, _query_id, _user_id, _msg_id, _data, _game_id); +inline MTPupdate MTP_updateInlineBotCallbackQuery(const MTPflags &_flags, const MTPlong &_query_id, MTPint _user_id, const MTPInputBotInlineMessageID &_msg_id, const MTPlong &_chat_instance, const MTPbytes &_data, MTPint _game_id) { + return MTP::internal::TypeCreator::new_updateInlineBotCallbackQuery(_flags, _query_id, _user_id, _msg_id, _chat_instance, _data, _game_id); } inline MTPupdate MTP_updateReadChannelOutbox(MTPint _channel_id, MTPint _max_id) { return MTP::internal::TypeCreator::new_updateReadChannelOutbox(_channel_id, _max_id); diff --git a/Telegram/SourceFiles/stickers/emoji_pan.cpp b/Telegram/SourceFiles/stickers/emoji_pan.cpp index a39f1e194..125aa4c6a 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.cpp +++ b/Telegram/SourceFiles/stickers/emoji_pan.cpp @@ -888,6 +888,21 @@ int StickerPanInner::countHeight(bool plain) { return qMax(minLastH, result) + st::stickerPanPadding; } +void StickerPanInner::installedLocally(uint64 setId) { + _installedLocallySets.insert(setId); +} + +void StickerPanInner::notInstalledLocally(uint64 setId) { + _installedLocallySets.remove(setId); +} + +void StickerPanInner::clearInstalledLocally() { + if (!_installedLocallySets.empty()) { + _installedLocallySets.clear(); + refreshStickers(); + } +} + StickerPanInner::~StickerPanInner() { clearInlineRows(true); deleteUnusedGifLayouts(); @@ -1009,6 +1024,11 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) { p.drawTextLeft(add.x() - (st::featuredStickersAdd.width / 2), add.y() + textTop, width(), _addText, _addWidth); widthForTitle -= add.width() - (st::featuredStickersAdd.width / 2); + } else { + auto add = featuredAddRect(c); + int checkx = add.left() + (add.width() - st::stickersFeaturedInstalled.width()) / 2; + int checky = add.top() + (add.height() - st::stickersFeaturedInstalled.height()) / 2; + st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width()); } if (set.flags & MTPDstickerSet_ClientFlag::f_unread) { widthForTitle -= st::stickersFeaturedUnreadSize + st::stickersFeaturedUnreadSkip; @@ -1362,6 +1382,7 @@ void StickerPanInner::hideFinish(bool completely) { for_const (auto item, _inlineLayouts) { itemForget(item); } + clearInstalledLocally(); } if (_setGifCommand && _section == Section::Gifs) { App::insertBotCommand(qsl(""), true); @@ -1404,7 +1425,7 @@ void StickerPanInner::refreshStickers() { _settings.hide(); } - emit refreshIcons(); + emit refreshIcons(kRefreshIconsNoAnimation); // Hack: skip over animations to the very end, // so that currently selected sticker won't get @@ -1497,7 +1518,7 @@ void StickerPanInner::refreshSavedGifs() { update(); } - emit refreshIcons(); + emit refreshIcons(kRefreshIconsNoAnimation); updateSelected(); } @@ -1763,7 +1784,7 @@ int StickerPanInner::refreshInlineRows(UserData *bot, const InlineCacheEntry *en if (h != height()) resize(width(), h); update(); - emit refreshIcons(); + emit refreshIcons(kRefreshIconsNoAnimation); _lastMousePos = QCursor::pos(); updateSelected(); @@ -1880,7 +1901,11 @@ void StickerPanInner::appendSet(Sets &to, uint64 setId, AppendSkip skip) { auto it = sets.constFind(setId); if (it == sets.cend() || it->stickers.isEmpty()) return; if ((skip == AppendSkip::Archived) && (it->flags & MTPDstickerSet::Flag::f_archived)) return; - if ((skip == AppendSkip::Installed) && (it->flags & MTPDstickerSet::Flag::f_installed) && !(it->flags & MTPDstickerSet::Flag::f_archived)) return; + if ((skip == AppendSkip::Installed) && (it->flags & MTPDstickerSet::Flag::f_installed) && !(it->flags & MTPDstickerSet::Flag::f_archived)) { + if (!_installedLocallySets.contains(setId)) { + return; + } + } to.push_back(Set(it->id, it->flags, it->title, it->stickers.size() + 1, it->stickers)); } @@ -2338,7 +2363,7 @@ void StickerPanInner::showStickerSet(uint64 setId) { _section = Section::Featured; refreshRecentStickers(true); - emit refreshIcons(); + emit refreshIcons(kRefreshIconsScrollAnimation); update(); } @@ -2364,7 +2389,7 @@ void StickerPanInner::showStickerSet(uint64 setId) { emit scrollUpdated(); if (needRefresh) { - emit refreshIcons(); + emit refreshIcons(kRefreshIconsScrollAnimation); } _lastMousePos = QCursor::pos(); @@ -2598,7 +2623,7 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent) connect(&s_inner, SIGNAL(displaySet(quint64)), this, SLOT(onDisplaySet(quint64))); connect(&s_inner, SIGNAL(installSet(quint64)), this, SLOT(onInstallSet(quint64))); connect(&s_inner, SIGNAL(removeSet(quint64)), this, SLOT(onRemoveSet(quint64))); - connect(&s_inner, SIGNAL(refreshIcons()), this, SLOT(onRefreshIcons())); + connect(&s_inner, SIGNAL(refreshIcons(bool)), this, SLOT(onRefreshIcons(bool))); connect(&e_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels())); connect(&s_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels())); @@ -2986,7 +3011,7 @@ void EmojiPan::refreshSavedGifs() { } } -void EmojiPan::onRefreshIcons() { +void EmojiPan::onRefreshIcons(bool scrollAnimation) { _iconOver = -1; _iconHovers.clear(); _iconAnimations.clear(); @@ -3008,7 +3033,7 @@ void EmojiPan::onRefreshIcons() { updatePanelsPositions(s_panels, s_scroll.scrollTop()); updateSelected(); if (_stickersShown) { - validateSelectedIcon(); + validateSelectedIcon(scrollAnimation ? ValidateIconAnimations::Scroll : ValidateIconAnimations::None); updateContentHeight(); } updateIcons(); @@ -3418,7 +3443,7 @@ void EmojiPan::onScrollStickers() { updatePanelsPositions(s_panels, st); - validateSelectedIcon(true); + validateSelectedIcon(ValidateIconAnimations::Full); if (st + s_scroll.height() > s_scroll.scrollTopMax()) { onInlineRequest(); } @@ -3426,7 +3451,7 @@ void EmojiPan::onScrollStickers() { s_inner.setVisibleTopBottom(st, st + s_scroll.height()); } -void EmojiPan::validateSelectedIcon(bool animated) { +void EmojiPan::validateSelectedIcon(ValidateIconAnimations animations) { uint64 setId = s_inner.currentSet(s_scroll.scrollTop()); int32 newSel = 0; for (int i = 0, l = _icons.size(); i < l; ++i) { @@ -3437,14 +3462,21 @@ void EmojiPan::validateSelectedIcon(bool animated) { } if (newSel != _iconSel) { _iconSel = newSel; - if (animated) { - _iconSelX.start(newSel * st::rbEmoji.width); + auto iconSelXFinal = newSel * st::rbEmoji.width; + if (animations == ValidateIconAnimations::Full) { + _iconSelX.start(iconSelXFinal); } else { - _iconSelX = anim::ivalue(newSel * st::rbEmoji.width, newSel * st::rbEmoji.width); + _iconSelX = anim::ivalue(iconSelXFinal, iconSelXFinal); + } + auto iconsXFinal = snap((2 * newSel - 7) * int(st::rbEmoji.width) / 2, 0, _iconsMax); + if (animations == ValidateIconAnimations::None) { + _iconsX = anim::ivalue(iconsXFinal, iconsXFinal); + _a_icons.stop(); + } else { + _iconsX.start(iconsXFinal); + _iconsStartAnim = getms(); + _a_icons.start(); } - _iconsX.start(snap((2 * newSel - 7) * int(st::rbEmoji.width) / 2, 0, _iconsMax)); - _iconsStartAnim = getms(); - _a_icons.start(); updateSelected(); updateIcons(); } @@ -3467,7 +3499,7 @@ void EmojiPan::onSwitch() { if (cShowingSavedGifs()) { s_inner.showFinish(); } - validateSelectedIcon(); + validateSelectedIcon(ValidateIconAnimations::None); updateContentHeight(); } _iconOver = -1; @@ -3513,7 +3545,7 @@ void EmojiPan::onInstallSet(quint64 setId) { auto it = sets.constFind(setId); if (it != sets.cend()) { MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_bool(false)), rpcDone(&EmojiPan::installSetDone), rpcFail(&EmojiPan::installSetFail, setId)); - + s_inner.installedLocally(setId); Stickers::installLocally(setId); } } @@ -3528,6 +3560,7 @@ bool EmojiPan::installSetFail(uint64 setId, const RPCError &error) { if (MTP::isDefaultHandledError(error)) { return false; } + s_inner.notInstalledLocally(setId); Stickers::undoInstallLocally(setId); return true; } diff --git a/Telegram/SourceFiles/stickers/emoji_pan.h b/Telegram/SourceFiles/stickers/emoji_pan.h index 16c8edc77..92da29b81 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.h +++ b/Telegram/SourceFiles/stickers/emoji_pan.h @@ -254,6 +254,10 @@ public: } int countHeight(bool plain = false); + void installedLocally(uint64 setId); + void notInstalledLocally(uint64 setId); + void clearInstalledLocally(); + ~StickerPanInner(); protected: @@ -281,7 +285,7 @@ signals: void installSet(quint64 setId); void removeSet(quint64 setId); - void refreshIcons(); + void refreshIcons(bool scrollAnimation); void emptyInlineRows(); void switchToEmoji(); @@ -294,6 +298,9 @@ signals: void saveConfigDelayed(int32 delay); private: + static constexpr bool kRefreshIconsScrollAnimation = true; + static constexpr bool kRefreshIconsNoAnimation = false; + struct Set { Set(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) { } @@ -346,6 +353,7 @@ private: Sets _mySets; Sets _featuredSets; + OrderedSet _installedLocallySets; QList _custom; enum class Section { @@ -527,10 +535,12 @@ public: } public slots: + void hideStart(); void refreshStickers(); + +private slots: void refreshSavedGifs(); - void hideStart(); void hideFinish(); void showStart(); @@ -547,7 +557,7 @@ public slots: void onRemoveSetSure(); void onDelayedHide(); - void onRefreshIcons(); + void onRefreshIcons(bool scrollAnimation); void onRefreshPanels(); void onSaveConfig(); @@ -572,7 +582,12 @@ private: void paintStickerSettingsIcon(Painter &p) const; void paintFeaturedStickerSetsBadge(Painter &p, int iconLeft) const; - void validateSelectedIcon(bool animated = false); + enum class ValidateIconAnimations { + Full, + Scroll, + None, + }; + void validateSelectedIcon(ValidateIconAnimations animations); void updateContentHeight(); void leaveToChildEvent(QEvent *e, QWidget *child); diff --git a/Telegram/SourceFiles/ui/emoji_config.h b/Telegram/SourceFiles/ui/emoji_config.h index 955811f11..a863a51fa 100644 --- a/Telegram/SourceFiles/ui/emoji_config.h +++ b/Telegram/SourceFiles/ui/emoji_config.h @@ -173,7 +173,7 @@ inline void appendPartToResult(QString &result, const QChar *start, const QChar if (entity.offset() >= from - start) { entity.extendToLeft(from - start - result.size()); } - if (entity.offset() + entity.length() < to - start) { + if (entity.offset() + entity.length() <= to - start) { entity.shrinkFromRight(from - start - result.size()); } } diff --git a/Telegram/build/makefile_static.sh b/Telegram/build/makefile_static.sh deleted file mode 100755 index 3aad822f3..000000000 --- a/Telegram/build/makefile_static.sh +++ /dev/null @@ -1,70 +0,0 @@ -set -e -FullExecPath=$PWD -pushd `dirname $0` > /dev/null -FullScriptPath=`pwd` -popd > /dev/null - -if [ ! -d "$FullScriptPath/../../../TelegramPrivate" ]; then - echo "" - echo "This script is for building the production version of Telegram Desktop." - echo "" - echo "For building custom versions please visit the build instructions page at:" - echo "https://github.com/telegramdesktop/tdesktop/#build-instructions" - exit 1 -fi - -Error () { - cd $FullExecPath - echo "$1" - exit 1 -} - -if [ ! -f "$FullScriptPath/target" ]; then - Error "Build target not found." -fi - -while IFS='' read -r line || [[ -n "$line" ]]; do - BuildTarget="$line" -done < "$FullScriptPath/target" - -LocalDirPath="\/usr\/local\/lib" -if [ "$BuildTarget" == "linux" ]; then - ArchDirPath="\/usr\/lib\/x86_64\-linux\-gnu" -elif [ "$BuildTarget" == "linux32" ]; then - ArchDirPath="\/usr\/lib\/i386\-linux\-gnu" -else - Error "Bad build target." -fi - -Replace () { - CheckCommand="grep -ci '$1' Makefile" - set +e - CheckCount=$(eval $CheckCommand) - set -e - if [ "$CheckCount" -gt 0 ]; then - echo "Requested '$1' to '$2', found - replacing.." - ReplaceCommand="sed -i'.~' 's/$1/$2/g' Makefile" - eval $ReplaceCommand - else - echo "Skipping '$1' to '$2'" - fi -} - -Replace '\-llzma' "$ArchDirPath\/liblzma\.a" -Replace '\-lXi' "$ArchDirPath\/libXi\.a $ArchDirPath\/libXext\.a" -Replace '\-lSM' "$ArchDirPath\/libSM\.a" -Replace '\-lICE' "$ArchDirPath\/libICE\.a" -Replace '\-lfontconfig' "$ArchDirPath\/libfontconfig\.a $ArchDirPath\/libexpat\.a" -Replace '\-lfreetype' "$ArchDirPath\/libfreetype\.a" -Replace '\-lXext' "$ArchDirPath\/libXext\.a" -Replace '\-lz' "$LocalDirPath\/libz\.a" -Replace '\-lopus' "$LocalDirPath\/libopus\.a" -Replace '\-lopenal' "$LocalDirPath\/libopenal\.a" -Replace '\-lavformat' "$LocalDirPath\/libavformat\.a" -Replace '\-lavcodec' "$LocalDirPath\/libavcodec\.a" -Replace '\-lswresample' "$LocalDirPath\/libswresample\.a" -Replace '\-lswscale' "$LocalDirPath\/libswscale\.a" -Replace '\-lavutil' "$LocalDirPath\/libavutil\.a" -Replace '\-lva-x11' "$LocalDirPath\/libva-x11\.a" -Replace '\-lva-drm' "$LocalDirPath\/libva-drm\.a" -Replace '\-lva' "$LocalDirPath\/libva\.a" diff --git a/Telegram/build/version b/Telegram/build/version index a1bfbfb6e..eefd756f7 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10006 +AppVersion 10007 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.6 -AppVersionStr 0.10.6 +AppVersionStrSmall 0.10.7 +AppVersionStr 0.10.7 AlphaChannel 0 BetaVersion 0 diff --git a/Telegram/gyp/qt.gypi b/Telegram/gyp/qt.gypi index 5ef32496a..2a8f0105c 100644 --- a/Telegram/gyp/qt.gypi +++ b/Telegram/gyp/qt.gypi @@ -92,8 +92,6 @@ 'Qt5DBus', 'Qt5Core', 'qtpcre', - 'ssl', - 'crypto', 'Xi', 'Xext', 'SM', @@ -206,6 +204,8 @@ 'libraries': [ '/usr/local/lib/libxkbcommon.a', '<@(qt_libs_release)', + '/usr/local/ssl/lib/libssl.a', + '/usr/local/ssl/lib/libcrypto.a', 'xcb', 'X11', 'X11-xcb',