diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index cf1d5800ef..eb5229d9f2 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -33,23 +33,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "window/themes/window_theme.h" #include "window/notifications_manager.h" +namespace { + +constexpr auto kReloadChannelMembersTimeout = 1000; // 1 second wait before reload members in channel after adding + +} // namespace + ApiWrap::ApiWrap(QObject *parent) : QObject(parent) -, _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) { +, _messageDataResolveDelayed([this] { resolveMessageDatas(); }) { Window::Theme::Background()->start(); - connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages())); - connect(&_draftsSaveTimer, SIGNAL(timeout()), this, SLOT(saveDraftsToCloud())); + connect(&_webPagesTimer, &QTimer::timeout, this, [this] { resolveWebPages(); }); + connect(&_draftsSaveTimer, &QTimer::timeout, this, [this] { saveDraftsToCloud(); }); } void ApiWrap::init() { } void ApiWrap::requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback) { - MessageDataRequest &req(channel ? _channelMessageDataRequests[channel][msgId] : _messageDataRequests[msgId]); + auto &req = (channel ? _channelMessageDataRequests[channel][msgId] : _messageDataRequests[msgId]); if (callback) { req.callbacks.append(callback); } - if (!req.req) _messageDataResolveDelayed->call(); + if (!req.req) _messageDataResolveDelayed.call(); } ApiWrap::MessageIds ApiWrap::collectMessageIds(const MessageDataRequests &requests) { @@ -202,7 +208,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt if (auto user = App::userLoaded(b.vuser_id.v)) { user->setBotInfo(item); App::clearPeerUpdated(user); - emit fullPeerUpdated(user); + fullPeerUpdated().notify(user); } } break; } @@ -274,7 +280,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt if (auto user = App::userLoaded(b.vuser_id.v)) { user->setBotInfo(item); App::clearPeerUpdated(user); - emit fullPeerUpdated(user); + fullPeerUpdated().notify(user); } } break; } @@ -320,7 +326,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt requestPeer(peer); } App::clearPeerUpdated(peer); - emit fullPeerUpdated(peer); + fullPeerUpdated().notify(peer); } void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) { @@ -353,7 +359,7 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestI } } App::clearPeerUpdated(peer); - emit fullPeerUpdated(peer); + fullPeerUpdated().notify(peer); } bool ApiWrap::gotPeerFullFailed(PeerData *peer, const RPCError &error) { @@ -563,7 +569,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP } peer->mgInfo->botStatus = botStatus; - if (App::main()) emit fullPeerUpdated(peer); + if (App::main()) fullPeerUpdated().notify(peer); } bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req) { @@ -669,7 +675,7 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt } } Notify::peerUpdatedDelayed(kick.first, Notify::PeerUpdate::Flag::MembersChanged); - emit fullPeerUpdated(kick.first); + fullPeerUpdated().notify(kick.first); } bool ApiWrap::kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req) { @@ -1345,10 +1351,10 @@ void ApiWrap::resolveWebPages() { if (m < INT_MAX) _webPagesTimer.start(m * 1000); } -void ApiWrap::delayedRequestParticipantsCount() { - if (App::main() && App::main()->peer() && App::main()->peer()->isChannel()) { - requestFullPeer(App::main()->peer()); - } +void ApiWrap::requestParticipantsCountDelayed(ChannelData *channel) { + QTimer::singleShot(kReloadChannelMembersTimeout, this, [this, channel] { + channel->updateFull(true); + }); } void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) { diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index cf1c6280f4..6fe06e5ee5 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -35,8 +35,6 @@ inline const MTPVector *getChatsFromMessagesChats(const MTPmessages_Cha } // namespace Api class ApiWrap : public QObject, public RPCSender { - Q_OBJECT - public: ApiWrap(QObject *parent); void init(); @@ -49,6 +47,7 @@ public: void requestPeers(const QList &peers); void requestLastParticipants(ChannelData *peer, bool fromStart = true); void requestBots(ChannelData *peer); + void requestParticipantsCountDelayed(ChannelData *channel); void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result); void processFullPeer(PeerData *peer, const MTPUserFull &result); @@ -73,6 +72,7 @@ public: void exportInviteLink(PeerData *peer); void requestNotifySetting(PeerData *peer); + void saveDraftsToCloud(); void saveDraftToCloudDelayed(History *history); bool hasUnsavedDrafts() const; @@ -80,21 +80,16 @@ public: void handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector &rules); int onlineTillFromStatus(const MTPUserStatus &status, int currentOnlineTill); + base::Observable &fullPeerUpdated() { + return _fullPeerUpdated; + } + ~ApiWrap(); -signals: - void fullPeerUpdated(PeerData *peer); - -public slots: - void resolveMessageDatas(); - void resolveWebPages(); - - void delayedRequestParticipantsCount(); - void saveDraftsToCloud(); - private: void updatesReceived(const MTPUpdates &updates); + void resolveMessageDatas(); void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req); struct MessageDataRequest { using Callbacks = QList; @@ -105,7 +100,7 @@ private: MessageDataRequests _messageDataRequests; typedef QMap ChannelMessageDataRequests; ChannelMessageDataRequests _channelMessageDataRequests; - SingleDelayedCall *_messageDataResolveDelayed; + SingleQueuedInvokation _messageDataResolveDelayed; typedef QVector MessageIds; MessageIds collectMessageIds(const MessageDataRequests &requests); MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false); @@ -138,6 +133,7 @@ private: typedef QMap SelfParticipantRequests; SelfParticipantRequests _selfParticipantRequests; + void resolveWebPages(); void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req); typedef QMap WebPagesPending; WebPagesPending _webPagesPending; @@ -191,4 +187,6 @@ private: void contactsStatusesDone(const MTPVector &result); bool contactsStatusesFail(const RPCError &error); + base::Observable _fullPeerUpdated; + }; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index b69c1184dc..ffb648700d 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -2466,7 +2466,9 @@ namespace { if (auto apiwrap = api()) { if (apiwrap->hasUnsavedDrafts()) { apiwrap->saveDraftsToCloud(); - QTimer::singleShot(SaveDraftBeforeQuitTimeout, QCoreApplication::instance(), SLOT(quit())); + QTimer::singleShot(SaveDraftBeforeQuitTimeout, [] { + QCoreApplication::quit(); + }); return; } } diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index fac7a256a1..aeb2d98384 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -26,7 +26,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "storage/localstorage.h" #include "autoupdater.h" #include "window/notifications_manager.h" -#include "base/task_queue.h" #include "messenger.h" namespace { @@ -347,10 +346,6 @@ void Application::closeApplication() { #endif // !TDESKTOP_DISABLE_AUTOUPDATE } -void Application::onMainThreadTask() { - base::TaskQueue::ProcessMainTasks(); -} - #ifndef TDESKTOP_DISABLE_AUTOUPDATE void Application::updateCheck() { startUpdateCheck(false); diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index 52ba9eec0b..eec0ffc84b 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -51,8 +51,6 @@ public slots: void startApplication(); // will be done in exec() void closeApplication(); // will be done in aboutToQuit() - void onMainThreadTask(); - private: typedef QPair LocalClient; typedef QList LocalClients; diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index a199670584..b3767f1878 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -1060,7 +1060,7 @@ bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) { if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) { if (_channel->setAbout(_sentDescription)) { if (App::api()) { - emit App::api()->fullPeerUpdated(_channel); + App::api()->fullPeerUpdated().notify(_channel); } } saveSign(); @@ -1090,7 +1090,7 @@ void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) { _saveDescriptionRequestId = 0; if (_channel->setAbout(_sentDescription)) { if (App::api()) { - emit App::api()->fullPeerUpdated(_channel); + App::api()->fullPeerUpdated().notify(_channel); } } saveSign(); diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 4bafcc5555..591a7e4d07 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -312,25 +312,21 @@ void ConvertToSupergroupBox::convertToSupergroup() { void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) { Ui::hideLayer(); App::main()->sentUpdatesReceived(updates); - const QVector *v = 0; - switch (updates.type()) { - case mtpc_updates: v = &updates.c_updates().vchats.v; break; - case mtpc_updatesCombined: v = &updates.c_updatesCombined().vchats.v; break; - default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break; - } - PeerData *peer = 0; - if (v && !v->isEmpty()) { - for (int32 i = 0, l = v->size(); i < l; ++i) { - if (v->at(i).type() == mtpc_channel) { - peer = App::channel(v->at(i).c_channel().vid.v); - Ui::showPeerHistory(peer, ShowAtUnreadMsgId); - QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount())); + auto handleChats = [](auto &mtpChats) { + for_const (auto &mtpChat, mtpChats.v) { + if (mtpChat.type() == mtpc_channel) { + auto channel = App::channel(mtpChat.c_channel().vid.v); + Ui::showPeerHistory(channel, ShowAtUnreadMsgId); + App::api()->requestParticipantsCountDelayed(channel); } } - } - if (!peer) { - LOG(("API Error: channel not found in updates (ProfileInner::migrateDone)")); + }; + + switch (updates.type()) { + case mtpc_updates: handleChats(updates.c_updates().vchats); break; + case mtpc_updatesCombined: handleChats(updates.c_updatesCombined().vchats); break; + default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break; } } diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 9b2479c465..1dcf814b61 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -62,6 +62,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org // return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition; //} +namespace { + +constexpr auto kReloadChannelAdminsTimeout = 1000; // 1 second wait before reload admins in channel after adding + +} // namespace + MembersBox::MembersBox(QWidget*, ChannelData *channel, MembersFilter filter) : _channel(channel) , _filter(filter) { @@ -124,7 +130,7 @@ void MembersBox::onAdminAdded() { if (!_addBox) return; _addBox->closeBox(); _addBox = nullptr; - _loadTimer->start(ReloadChannelMembersTimeout); + _loadTimer->start(kReloadChannelAdminsTimeout); } MembersBox::Inner::Inner(QWidget *parent, ChannelData *channel, MembersFilter filter) : TWidget(parent) diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index eb269a1cd3..df28c96887 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -142,7 +142,6 @@ enum { SessionsShortPollTimeout = 60000, ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file - ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding }; inline bool isNotificationsUser(uint64 id) { diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 6a294454b8..a2fdfb84a9 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -28,6 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "layerwidget.h" #include "lang.h" #include "base/observer.h" +#include "base/task_queue.h" Q_DECLARE_METATYPE(ClickHandlerPtr); Q_DECLARE_METATYPE(Qt::MouseButton); @@ -410,7 +411,7 @@ struct Data { } // namespace internal } // namespace Sandbox -Sandbox::internal::Data *SandboxData = nullptr; +std::unique_ptr SandboxData; uint64 SandboxUserTag = 0; namespace Sandbox { @@ -496,7 +497,7 @@ void WorkingDirReady() { } } -object_ptr MainThreadTaskHandler = { nullptr }; +object_ptr MainThreadTaskHandler = { nullptr }; void MainThreadTaskAdded() { if (!started()) { @@ -507,8 +508,10 @@ void MainThreadTaskAdded() { } void start() { - MainThreadTaskHandler.create(QCoreApplication::instance(), "onMainThreadTask"); - SandboxData = new internal::Data(); + MainThreadTaskHandler.create([] { + base::TaskQueue::ProcessMainTasks(); + }); + SandboxData = std::make_unique(); SandboxData->LangSystemISO = psCurrentLanguage(); if (SandboxData->LangSystemISO.isEmpty()) SandboxData->LangSystemISO = qstr("en"); @@ -526,8 +529,7 @@ bool started() { } void finish() { - delete SandboxData; - SandboxData = nullptr; + SandboxData.reset(); MainThreadTaskHandler.destroy(); } @@ -586,10 +588,10 @@ namespace internal { struct Data { uint64 LaunchId = 0; - SingleDelayedCall HandleHistoryUpdate = { App::app(), "call_handleHistoryUpdate" }; - SingleDelayedCall HandleUnreadCounterUpdate = { App::app(), "call_handleUnreadCounterUpdate" }; - SingleDelayedCall HandleDelayedPeerUpdates = { App::app(), "call_handleDelayedPeerUpdates" }; - SingleDelayedCall HandleObservables = { App::app(), "call_handleObservables" }; + SingleQueuedInvokation HandleHistoryUpdate = { [] { App::app()->call_handleHistoryUpdate(); } }; + SingleQueuedInvokation HandleUnreadCounterUpdate = { [] { App::app()->call_handleUnreadCounterUpdate(); } }; + SingleQueuedInvokation HandleDelayedPeerUpdates = { [] { App::app()->call_handleDelayedPeerUpdates(); } }; + SingleQueuedInvokation HandleObservables = { [] { App::app()->call_handleObservables(); } }; Adaptive::WindowLayout AdaptiveWindowLayout = Adaptive::WindowLayout::Normal; Adaptive::ChatLayout AdaptiveChatLayout = Adaptive::ChatLayout::Normal; @@ -709,10 +711,10 @@ void finish() { } DefineReadOnlyVar(Global, uint64, LaunchId); -DefineRefVar(Global, SingleDelayedCall, HandleHistoryUpdate); -DefineRefVar(Global, SingleDelayedCall, HandleUnreadCounterUpdate); -DefineRefVar(Global, SingleDelayedCall, HandleDelayedPeerUpdates); -DefineRefVar(Global, SingleDelayedCall, HandleObservables); +DefineRefVar(Global, SingleQueuedInvokation, HandleHistoryUpdate); +DefineRefVar(Global, SingleQueuedInvokation, HandleUnreadCounterUpdate); +DefineRefVar(Global, SingleQueuedInvokation, HandleDelayedPeerUpdates); +DefineRefVar(Global, SingleQueuedInvokation, HandleObservables); DefineVar(Global, Adaptive::WindowLayout, AdaptiveWindowLayout); DefineVar(Global, Adaptive::ChatLayout, AdaptiveChatLayout); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 7dac46ea39..26e806a869 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -292,10 +292,10 @@ void start(); void finish(); DeclareReadOnlyVar(uint64, LaunchId); -DeclareRefVar(SingleDelayedCall, HandleHistoryUpdate); -DeclareRefVar(SingleDelayedCall, HandleUnreadCounterUpdate); -DeclareRefVar(SingleDelayedCall, HandleDelayedPeerUpdates); -DeclareRefVar(SingleDelayedCall, HandleObservables); +DeclareRefVar(SingleQueuedInvokation, HandleHistoryUpdate); +DeclareRefVar(SingleQueuedInvokation, HandleUnreadCounterUpdate); +DeclareRefVar(SingleQueuedInvokation, HandleDelayedPeerUpdates); +DeclareRefVar(SingleQueuedInvokation, HandleObservables); DeclareVar(Adaptive::WindowLayout, AdaptiveWindowLayout); DeclareVar(Adaptive::ChatLayout, AdaptiveChatLayout); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 580d4606f3..a7f9ba1e36 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -152,7 +152,8 @@ HistoryInner::HistoryInner(HistoryWidget *historyWidget, Ui::ScrollArea *scroll, , _migrated(history->peer->migrateFrom() ? App::history(history->peer->migrateFrom()->id) : nullptr) , _history(history) , _widget(historyWidget) -, _scroll(scroll) { +, _scroll(scroll) +, _scrollDateCheck([this] { onScrollDateCheck(); }) { _touchSelectTimer.setSingleShot(true); connect(&_touchSelectTimer, SIGNAL(timeout()), this, SLOT(onTouchSelect())); @@ -2585,7 +2586,7 @@ void MessageField::focusInEvent(QFocusEvent *e) { emit focused(); } -ReportSpamPanel::ReportSpamPanel(HistoryWidget *parent) : TWidget(parent), +ReportSpamPanel::ReportSpamPanel(QWidget *parent) : TWidget(parent), _report(this, lang(lng_report_spam), st::reportSpamHide), _hide(this, lang(lng_report_spam_hide), st::reportSpamHide), _clear(this, lang(lng_profile_delete_conversation)) { @@ -3369,8 +3370,9 @@ void HistoryWidget::start() { connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated())); updateRecentStickers(); AuthSession::Current().data().savedGifsUpdated().notify(); - - connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*))); + subscribe(App::api()->fullPeerUpdated(), [this](PeerData *peer) { + fullPeerUpdated(peer); + }); } void HistoryWidget::onStickersUpdated() { @@ -8397,8 +8399,8 @@ void HistoryWidget::onCancel() { } } -void HistoryWidget::onFullPeerUpdated(PeerData *data) { - if (_list && data == _peer) { +void HistoryWidget::fullPeerUpdated(PeerData *peer) { + if (_list && peer == _peer) { bool newCanSendMessages = canSendMessages(_peer); if (newCanSendMessages != _canSendMessages) { _canSendMessages = newCanSendMessages; @@ -8422,9 +8424,9 @@ void HistoryWidget::onFullPeerUpdated(PeerData *data) { void HistoryWidget::peerUpdated(PeerData *data) { if (data && data == _peer) { - if (data->migrateTo()) { - Ui::showPeerHistory(data->migrateTo(), ShowAtUnreadMsgId); - QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount())); + if (auto channel = data->migrateTo()) { + Ui::showPeerHistory(channel, ShowAtUnreadMsgId); + App::api()->requestParticipantsCountDelayed(channel); return; } QString restriction = _peer->restrictionReason(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index e3efef33d6..5ce0ca6d09 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -286,7 +286,7 @@ private: bool _scrollDateShown = false; Animation _scrollDateOpacity; - SingleDelayedCall _scrollDateCheck = { this, "onScrollDateCheck" }; + SingleQueuedInvokation _scrollDateCheck; SingleTimer _scrollDateHideTimer; HistoryItem *_scrollDateLastItem = nullptr; int _scrollDateLastItemTop = 0; @@ -358,12 +358,11 @@ private: }; -class HistoryWidget; class ReportSpamPanel : public TWidget { Q_OBJECT public: - ReportSpamPanel(HistoryWidget *parent); + ReportSpamPanel(QWidget *parent); void setReported(bool reported, PeerData *onPeer); @@ -767,7 +766,6 @@ public slots: void onPreviewTimeout(); void peerUpdated(PeerData *data); - void onFullPeerUpdated(PeerData *data); void onPhotoUploaded(const FullMsgId &msgId, bool silent, const MTPInputFile &file); void onDocumentUploaded(const FullMsgId &msgId, bool silent, const MTPInputFile &file); @@ -856,6 +854,7 @@ private: bool allFilesForCompress = true; }; + void fullPeerUpdated(PeerData *peer); void topBarClick(); void animationCallback(); diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index 2cecf01ab8..8dece22354 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "base/runtime_composer.h" -static constexpr TextSelection FullSelection = { 0xFFFF, 0xFFFF }; +constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF }; extern TextParseOptions _textNameOptions, _textDlgOptions; extern TextParseOptions _historyTextOptions, _historyBotOptions, _historyTextNoMonoOptions, _historyBotNoMonoOptions; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ebcf0359b9..3e45d580e9 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -102,7 +102,6 @@ MainWidget::MainWidget(QWidget *parent, std::unique_ptr cont connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeByPts())); connect(&_byMinChannelTimer, SIGNAL(timeout()), this, SLOT(getDifference())); connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeAfterFail())); - connect(_api.get(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*))); connect(this, SIGNAL(peerUpdated(PeerData*)), _history, SLOT(peerUpdated(PeerData*))); connect(_history, SIGNAL(historyShown(History*,MsgId)), this, SLOT(onHistoryShown(History*,MsgId))); connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings())); @@ -111,7 +110,9 @@ MainWidget::MainWidget(QWidget *parent, std::unique_ptr cont handleAudioUpdate(audioId); } }); - + subscribe(_api->fullPeerUpdated(), [this](PeerData *peer) { + emit peerUpdated(peer); + }); subscribe(Global::RefDialogsListFocused(), [this](bool) { updateDialogsWidthAnimated(); }); @@ -2797,13 +2798,7 @@ bool MainWidget::deleteChannelFailed(const RPCError &error) { void MainWidget::inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates) { sentUpdatesReceived(updates); - QTimer::singleShot(ReloadChannelMembersTimeout, this, SLOT(onActiveChannelUpdateFull())); -} - -void MainWidget::onActiveChannelUpdateFull() { - if (activePeer() && activePeer()->isChannel()) { - activePeer()->asChannel()->updateFull(true); - } + App::api()->requestParticipantsCountDelayed(channel); } void MainWidget::historyToDown(History *history) { @@ -3830,10 +3825,6 @@ void MainWidget::onStickersInstalled(uint64 setId) { _history->stickersInstalled(setId); } -void MainWidget::onFullPeerUpdated(PeerData *peer) { - emit peerUpdated(peer); -} - void MainWidget::onSelfParticipantUpdated(ChannelData *channel) { auto history = App::historyLoaded(channel->id); if (_updatedChannels.contains(channel)) { @@ -5062,7 +5053,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { if (channel->isMegagroup()) { channel->mgInfo->pinnedMsgId = d.vid.v; if (App::api()) { - emit App::api()->fullPeerUpdated(channel); + App::api()->fullPeerUpdated().notify(channel); } } } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 90ed7844d9..52f198cad5 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -444,10 +444,8 @@ public slots: void onUpdateMuted(); void onStickersInstalled(uint64 setId); - void onFullPeerUpdated(PeerData *peer); void onViewsIncrement(); - void onActiveChannelUpdateFull(); void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way); void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId); diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index 2cc36249ab..9fba602ae3 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.cpp +++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp @@ -27,7 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Media { namespace Player { -Loaders::Loaders(QThread *thread) : _fromVideoNotify(this, "onVideoSoundAdded") { +Loaders::Loaders(QThread *thread) : _fromVideoNotify([this] { videoSoundAdded(); }) { moveToThread(thread); connect(thread, SIGNAL(started()), this, SLOT(onInit())); connect(thread, SIGNAL(finished()), this, SLOT(deleteLater())); @@ -59,7 +59,7 @@ void Loaders::stopFromVideo() { startFromVideo(0); } -void Loaders::onVideoSoundAdded() { +void Loaders::videoSoundAdded() { bool waitingAndAdded = false; { QMutexLocker lock(&_fromVideoMutex); diff --git a/Telegram/SourceFiles/media/media_audio_loaders.h b/Telegram/SourceFiles/media/media_audio_loaders.h index a0a676d9fe..e2efd57ed0 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.h +++ b/Telegram/SourceFiles/media/media_audio_loaders.h @@ -51,9 +51,8 @@ signals: void onLoad(const AudioMsgId &audio); void onCancel(const AudioMsgId &audio); - void onVideoSoundAdded(); - private: + void videoSoundAdded(); void clearFromVideoQueue(); AudioMsgId _audio, _song, _video; @@ -64,7 +63,7 @@ private: QMutex _fromVideoMutex; uint64 _fromVideoPlayId; QQueue _fromVideoQueue; - SingleDelayedCall _fromVideoNotify; + SingleQueuedInvokation _fromVideoNotify; void emitError(AudioMsgId::Type type); AudioMsgId clear(AudioMsgId::Type type); diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index ea7803f09f..0d47b60054 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -55,8 +55,7 @@ struct Messenger::Private { }; Messenger::Messenger() : QObject() -, _private(std::make_unique()) -, _delayedLoadersDestroyer(this, "onDelayedDestroyLoaders") { +, _private(std::make_unique()) { t_assert(SingleInstance == nullptr); SingleInstance = this; @@ -697,7 +696,6 @@ void Messenger::prepareToDestroy() { // Some MTP requests can be cancelled from data clearing. App::clearHistories(); - _delayedDestroyedLoaders.clear(); authSessionDestroy(); _mtproto.reset(); @@ -732,12 +730,3 @@ Messenger::~Messenger() { MainWindow *Messenger::mainWindow() { return _window.get(); } - -void Messenger::delayedDestroyLoader(std::unique_ptr loader) { - _delayedDestroyedLoaders.push_back(std::move(loader)); - _delayedLoadersDestroyer.call(); -} - -void Messenger::onDelayedDestroyLoaders() { - _delayedDestroyedLoaders.clear(); -} diff --git a/Telegram/SourceFiles/messenger.h b/Telegram/SourceFiles/messenger.h index f1230680c3..807e2069b3 100644 --- a/Telegram/SourceFiles/messenger.h +++ b/Telegram/SourceFiles/messenger.h @@ -105,8 +105,10 @@ public: void handleAppActivated(); void handleAppDeactivated(); - // Temporary here, when all Images and Documents are owned by AuthSession it'll have this. - void delayedDestroyLoader(std::unique_ptr loader); + void call_handleHistoryUpdate(); + void call_handleUnreadCounterUpdate(); + void call_handleDelayedPeerUpdates(); + void call_handleObservables(); signals: void peerPhotoDone(PeerId peer); @@ -114,7 +116,6 @@ signals: public slots: void onAllKeysDestroyed(); - void onDelayedDestroyLoaders(); void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file); @@ -125,11 +126,6 @@ public slots: void killDownloadSessions(); void onAppStateChanged(Qt::ApplicationState state); - void call_handleHistoryUpdate(); - void call_handleUnreadCounterUpdate(); - void call_handleDelayedPeerUpdates(); - void call_handleObservables(); - private: void destroyMtpKeys(MTP::AuthKeysList &&keys); void startLocalStorage(); @@ -154,7 +150,4 @@ private: std::unique_ptr _authSession; base::Observable _authSessionChanged; - SingleDelayedCall _delayedLoadersDestroyer; - std::vector> _delayedDestroyedLoaders; - }; diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp index 959766feea..48aaa2a67c 100644 --- a/Telegram/SourceFiles/storage/file_download.cpp +++ b/Telegram/SourceFiles/storage/file_download.cpp @@ -29,6 +29,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org namespace Storage { +Downloader::Downloader() +: _delayedLoadersDestroyer([this] { _delayedDestroyedLoaders.clear(); }) { +} + +void Downloader::delayedDestroyLoader(std::unique_ptr loader) { + _delayedDestroyedLoaders.push_back(std::move(loader)); + _delayedLoadersDestroyer.call(); +} + void Downloader::clearPriorities() { ++_priority; } diff --git a/Telegram/SourceFiles/storage/file_download.h b/Telegram/SourceFiles/storage/file_download.h index c80a564116..8ca8d46b58 100644 --- a/Telegram/SourceFiles/storage/file_download.h +++ b/Telegram/SourceFiles/storage/file_download.h @@ -27,11 +27,15 @@ namespace Storage { class Downloader final { public: + Downloader(); + int currentPriority() const { return _priority; } void clearPriorities(); + void delayedDestroyLoader(std::unique_ptr loader); + base::Observable &taskFinished() { return _taskFinishedObservable; } @@ -40,6 +44,9 @@ private: base::Observable _taskFinishedObservable; int _priority = 1; + SingleQueuedInvokation _delayedLoadersDestroyer; + std::vector> _delayedDestroyedLoaders; + }; } // namespace Storage diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index cbebdc401c..9476bbced9 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -1535,7 +1535,7 @@ bool DocumentData::loaded(FilePathResolveType type) const { void DocumentData::destroyLoaderDelayed(mtpFileLoader *newValue) const { _loader->stop(); auto loader = std::unique_ptr(std::exchange(_loader, newValue)); - Messenger::Instance().delayedDestroyLoader(std::move(loader)); + AuthSession::Current().downloader().delayedDestroyLoader(std::move(loader)); } bool DocumentData::loading() const { @@ -1620,10 +1620,10 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs void DocumentData::cancel() { if (!loading()) return; - auto loader = std::exchange(_loader, CancelledMtpFileLoader); + auto loader = std::unique_ptr(std::exchange(_loader, CancelledMtpFileLoader)); loader->cancel(); loader->stop(); - Messenger::Instance().delayedDestroyLoader(std::unique_ptr(loader)); + AuthSession::Current().downloader().delayedDestroyLoader(std::move(loader)); notifyLayoutChanged(); if (auto main = App::main()) { diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index d4a9e70e70..2a32d943dd 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "storage/localstorage.h" #include "platform/platform_specific.h" -#include "messenger.h" +#include "auth_session.h" namespace Images { namespace { @@ -858,7 +858,7 @@ void RemoteImage::doCheckload() const { void RemoteImage::destroyLoaderDelayed(FileLoader *newValue) const { _loader->stop(); auto loader = std::unique_ptr(std::exchange(_loader, newValue)); - Messenger::Instance().delayedDestroyLoader(std::move(loader)); + AuthSession::Current().downloader().delayedDestroyLoader(std::move(loader)); } void RemoteImage::loadLocal() { @@ -959,7 +959,7 @@ void RemoteImage::cancel() { auto loader = std::exchange(_loader, CancelledFileLoader); loader->cancel(); loader->stop(); - Messenger::Instance().delayedDestroyLoader(std::unique_ptr(loader)); + AuthSession::Current().downloader().delayedDestroyLoader(std::unique_ptr(loader)); } float64 RemoteImage::progress() const { diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h index 55fd4eb700..d3f7f5af6b 100644 --- a/Telegram/SourceFiles/ui/twidget.h +++ b/Telegram/SourceFiles/ui/twidget.h @@ -328,28 +328,23 @@ void myEnsureResized(QWidget *target); QPixmap myGrab(TWidget *target, QRect rect = QRect(), QColor bg = QColor(255, 255, 255, 0)); QImage myGrabImage(TWidget *target, QRect rect = QRect(), QColor bg = QColor(255, 255, 255, 0)); -class SingleDelayedCall : public QObject { - Q_OBJECT - +class SingleQueuedInvokation : public QObject { public: - SingleDelayedCall(QObject *parent, const char *member) : QObject(parent), _member(member) { + SingleQueuedInvokation(base::lambda callback) : _callback(callback) { } void call() { - if (_pending.testAndSetOrdered(0, 1)) { - QMetaObject::invokeMethod(this, "makeDelayedCall", Qt::QueuedConnection); - } - } - -private slots: - void makeDelayedCall() { - if (_pending.testAndSetOrdered(1, 0)) { - QMetaObject::invokeMethod(parent(), _member); + if (_pending.testAndSetAcquire(0, 1)) { + InvokeQueued(this, [this] { + if (_pending.testAndSetRelease(1, 0)) { + _callback(); + } + }); } } private: + base::lambda _callback; QAtomicInt _pending = { 0 }; - const char *_member; };