Moved views increment scheduler from MainWidget to separate file.
This commit is contained in:
parent
51e80170e2
commit
21aa1f49d7
|
@ -139,6 +139,8 @@ PRIVATE
|
|||
api/api_updates.h
|
||||
api/api_user_privacy.cpp
|
||||
api/api_user_privacy.h
|
||||
api/api_views.cpp
|
||||
api/api_views.h
|
||||
api/api_who_read.cpp
|
||||
api/api_who_read.h
|
||||
boxes/filters/edit_filter_box.cpp
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_views.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_peer_id.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
// Send channel views each second.
|
||||
constexpr auto kSendViewsTimeout = crl::time(1000);
|
||||
|
||||
} // namespace
|
||||
|
||||
ViewsManager::ViewsManager(not_null<ApiWrap*> api)
|
||||
: _session(&api->session())
|
||||
, _api(&api->instance()) {
|
||||
}
|
||||
|
||||
void ViewsManager::scheduleIncrement(not_null<HistoryItem*> item) {
|
||||
auto peer = item->history()->peer;
|
||||
auto i = _incremented.find(peer);
|
||||
if (i != _incremented.cend()) {
|
||||
if (i->second.contains(item->id)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
i = _incremented.emplace(peer).first;
|
||||
}
|
||||
i->second.emplace(item->id);
|
||||
auto j = _toIncrement.find(peer);
|
||||
if (j == _toIncrement.cend()) {
|
||||
j = _toIncrement.emplace(peer).first;
|
||||
_incrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
j->second.emplace(item->id);
|
||||
}
|
||||
|
||||
void ViewsManager::removeIncremented(not_null<PeerData*> peer) {
|
||||
_incremented.remove(peer);
|
||||
}
|
||||
|
||||
void ViewsManager::viewsIncrement() {
|
||||
for (auto i = _toIncrement.begin(); i != _toIncrement.cend();) {
|
||||
if (_incrementRequests.contains(i->first)) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<MTPint> ids;
|
||||
ids.reserve(i->second.size());
|
||||
for (const auto msgId : i->second) {
|
||||
ids.push_back(MTP_int(msgId));
|
||||
}
|
||||
const auto requestId = _api.request(MTPmessages_GetMessagesViews(
|
||||
i->first->input,
|
||||
MTP_vector<MTPint>(ids),
|
||||
MTP_bool(true)
|
||||
)).done([=](
|
||||
const MTPmessages_MessageViews &result,
|
||||
mtpRequestId requestId) {
|
||||
done(ids, result, requestId);
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
fail(error, requestId);
|
||||
}).afterDelay(5).send();
|
||||
|
||||
_incrementRequests.emplace(i->first, requestId);
|
||||
i = _toIncrement.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::done(
|
||||
QVector<MTPint> ids,
|
||||
const MTPmessages_MessageViews &result,
|
||||
mtpRequestId requestId) {
|
||||
const auto &data = result.c_messages_messageViews();
|
||||
auto &owner = _session->data();
|
||||
owner.processUsers(data.vusers());
|
||||
owner.processChats(data.vchats());
|
||||
auto &v = data.vviews().v;
|
||||
if (ids.size() == v.size()) {
|
||||
for (const auto &[peer, id] : _incrementRequests) {
|
||||
if (id != requestId) {
|
||||
continue;
|
||||
}
|
||||
const auto channel = peerToChannel(peer->id);
|
||||
for (auto j = 0, l = int(ids.size()); j < l; ++j) {
|
||||
if (const auto item = owner.message(channel, ids[j].v)) {
|
||||
v[j].match([&](const MTPDmessageViews &data) {
|
||||
if (const auto views = data.vviews()) {
|
||||
item->setViewsCount(views->v);
|
||||
}
|
||||
if (const auto forwards = data.vforwards()) {
|
||||
item->setForwardsCount(forwards->v);
|
||||
}
|
||||
if (const auto replies = data.vreplies()) {
|
||||
item->setReplies(*replies);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_incrementRequests.erase(peer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!_toIncrement.empty() && !_incrementTimer.isActive()) {
|
||||
_incrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::fail(const MTP::Error &error, mtpRequestId requestId) {
|
||||
for (const auto &[peer, id] : _incrementRequests) {
|
||||
if (id == requestId) {
|
||||
_incrementRequests.erase(peer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!_toIncrement.empty() && !_incrementTimer.isActive()) {
|
||||
_incrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Api
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
class ApiWrap;
|
||||
class PeerData;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Api {
|
||||
|
||||
class ViewsManager final {
|
||||
public:
|
||||
explicit ViewsManager(not_null<ApiWrap*> api);
|
||||
|
||||
void scheduleIncrement(not_null<HistoryItem*> item);
|
||||
void removeIncremented(not_null<PeerData*> peer);
|
||||
|
||||
private:
|
||||
void viewsIncrement();
|
||||
|
||||
void done(
|
||||
QVector<MTPint> ids,
|
||||
const MTPmessages_MessageViews &result,
|
||||
mtpRequestId requestId);
|
||||
void fail(const MTP::Error &error, mtpRequestId requestId);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
MTP::Sender _api;
|
||||
|
||||
base::flat_map<not_null<PeerData*>, base::flat_set<MsgId>> _incremented;
|
||||
base::flat_map<not_null<PeerData*>, base::flat_set<MsgId>> _toIncrement;
|
||||
base::flat_map<not_null<PeerData*>, mtpRequestId> _incrementRequests;
|
||||
base::flat_map<mtpRequestId, not_null<PeerData*>> _incrementByRequest;
|
||||
base::Timer _incrementTimer;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_global_privacy.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "api/api_user_privacy.h"
|
||||
#include "api/api_views.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_changes.h"
|
||||
|
@ -141,7 +142,8 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
|
|||
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this))
|
||||
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this))
|
||||
, _userPrivacy(std::make_unique<Api::UserPrivacy>(this))
|
||||
, _inviteLinks(std::make_unique<Api::InviteLinks>(this)) {
|
||||
, _inviteLinks(std::make_unique<Api::InviteLinks>(this))
|
||||
, _views(std::make_unique<Api::ViewsManager>(this)) {
|
||||
crl::on_main(session, [=] {
|
||||
// You can't use _session->lifetime() in the constructor,
|
||||
// only queued, because it is not constructed yet.
|
||||
|
@ -4733,6 +4735,10 @@ Api::InviteLinks &ApiWrap::inviteLinks() {
|
|||
return *_inviteLinks;
|
||||
}
|
||||
|
||||
Api::ViewsManager &ApiWrap::views() {
|
||||
return *_views;
|
||||
}
|
||||
|
||||
void ApiWrap::createPoll(
|
||||
const PollData &data,
|
||||
const SendAction &action,
|
||||
|
|
|
@ -62,6 +62,7 @@ class SensitiveContent;
|
|||
class GlobalPrivacy;
|
||||
class UserPrivacy;
|
||||
class InviteLinks;
|
||||
class ViewsManager;
|
||||
|
||||
namespace details {
|
||||
|
||||
|
@ -400,6 +401,7 @@ public:
|
|||
[[nodiscard]] Api::GlobalPrivacy &globalPrivacy();
|
||||
[[nodiscard]] Api::UserPrivacy &userPrivacy();
|
||||
[[nodiscard]] Api::InviteLinks &inviteLinks();
|
||||
[[nodiscard]] Api::ViewsManager &views();
|
||||
|
||||
void createPoll(
|
||||
const PollData &data,
|
||||
|
@ -720,6 +722,7 @@ private:
|
|||
const std::unique_ptr<Api::GlobalPrivacy> _globalPrivacy;
|
||||
const std::unique_ptr<Api::UserPrivacy> _userPrivacy;
|
||||
const std::unique_ptr<Api::InviteLinks> _inviteLinks;
|
||||
const std::unique_ptr<Api::ViewsManager> _views;
|
||||
|
||||
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
|
||||
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;
|
||||
|
|
|
@ -58,6 +58,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_attached_stickers.h"
|
||||
#include "api/api_toggling_media.h"
|
||||
#include "api/api_who_read.h"
|
||||
#include "api/api_views.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_media_types.h"
|
||||
|
@ -677,7 +678,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
view->draw(p, context);
|
||||
|
||||
if (item->hasViews()) {
|
||||
_controller->content()->scheduleViewIncrement(item);
|
||||
session().api().views().scheduleIncrement(item);
|
||||
}
|
||||
if (item->isUnreadMention() && !item->isUnreadMedia()) {
|
||||
readMentions.insert(item);
|
||||
|
@ -737,7 +738,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
if (_visibleAreaBottom >= middle
|
||||
&& _visibleAreaTop <= middle) {
|
||||
if (item->hasViews()) {
|
||||
_controller->content()->scheduleViewIncrement(item);
|
||||
session().api().views().scheduleIncrement(item);
|
||||
}
|
||||
if (item->isUnreadMention() && !item->isUnreadMedia()) {
|
||||
readMentions.insert(item);
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "mainwidget.h"
|
||||
|
||||
#include "api/api_updates.h"
|
||||
#include "api/api_views.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
|
@ -116,13 +117,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
namespace {
|
||||
|
||||
// Send channel views each second.
|
||||
constexpr auto kSendViewsTimeout = crl::time(1000);
|
||||
|
||||
} // namespace
|
||||
|
||||
enum StackItemType {
|
||||
HistoryStackItem,
|
||||
SectionStackItem,
|
||||
|
@ -235,7 +229,6 @@ MainWidget::MainWidget(
|
|||
, _dialogs(this, _controller)
|
||||
, _history(this, _controller)
|
||||
, _playerPlaylist(this, _controller)
|
||||
, _viewsIncrementTimer([=] { viewsIncrement(); })
|
||||
, _changelogs(Core::Changelogs::Create(&controller->session())) {
|
||||
setupConnectingWidget();
|
||||
|
||||
|
@ -1221,100 +1214,6 @@ void MainWidget::setInnerFocus() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWidget::scheduleViewIncrement(HistoryItem *item) {
|
||||
PeerData *peer = item->history()->peer;
|
||||
auto i = _viewsIncremented.find(peer);
|
||||
if (i != _viewsIncremented.cend()) {
|
||||
if (i->second.contains(item->id)) return;
|
||||
} else {
|
||||
i = _viewsIncremented.emplace(peer).first;
|
||||
}
|
||||
i->second.emplace(item->id);
|
||||
auto j = _viewsToIncrement.find(peer);
|
||||
if (j == _viewsToIncrement.cend()) {
|
||||
j = _viewsToIncrement.emplace(peer).first;
|
||||
_viewsIncrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
j->second.emplace(item->id);
|
||||
}
|
||||
|
||||
void MainWidget::viewsIncrement() {
|
||||
for (auto i = _viewsToIncrement.begin(); i != _viewsToIncrement.cend();) {
|
||||
if (_viewsIncrementRequests.contains(i->first)) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<MTPint> ids;
|
||||
ids.reserve(i->second.size());
|
||||
for (const auto msgId : i->second) {
|
||||
ids.push_back(MTP_int(msgId));
|
||||
}
|
||||
const auto requestId = _api.request(MTPmessages_GetMessagesViews(
|
||||
i->first->input,
|
||||
MTP_vector<MTPint>(ids),
|
||||
MTP_bool(true)
|
||||
)).done([=](const MTPmessages_MessageViews &result, mtpRequestId requestId) {
|
||||
viewsIncrementDone(ids, result, requestId);
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
viewsIncrementFail(error, requestId);
|
||||
}).afterDelay(5).send();
|
||||
|
||||
_viewsIncrementRequests.emplace(i->first, requestId);
|
||||
i = _viewsToIncrement.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::viewsIncrementDone(
|
||||
QVector<MTPint> ids,
|
||||
const MTPmessages_MessageViews &result,
|
||||
mtpRequestId requestId) {
|
||||
const auto &data = result.c_messages_messageViews();
|
||||
session().data().processUsers(data.vusers());
|
||||
session().data().processChats(data.vchats());
|
||||
auto &v = data.vviews().v;
|
||||
if (ids.size() == v.size()) {
|
||||
for (auto i = _viewsIncrementRequests.begin(); i != _viewsIncrementRequests.cend(); ++i) {
|
||||
if (i->second == requestId) {
|
||||
const auto peer = i->first;
|
||||
const auto channel = peerToChannel(peer->id);
|
||||
for (int32 j = 0, l = ids.size(); j < l; ++j) {
|
||||
if (const auto item = session().data().message(channel, ids[j].v)) {
|
||||
v[j].match([&](const MTPDmessageViews &data) {
|
||||
if (const auto views = data.vviews()) {
|
||||
item->setViewsCount(views->v);
|
||||
}
|
||||
if (const auto forwards = data.vforwards()) {
|
||||
item->setForwardsCount(forwards->v);
|
||||
}
|
||||
if (const auto replies = data.vreplies()) {
|
||||
item->setReplies(*replies);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_viewsIncrementRequests.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_viewsToIncrement.empty() && !_viewsIncrementTimer.isActive()) {
|
||||
_viewsIncrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::viewsIncrementFail(const MTP::Error &error, mtpRequestId requestId) {
|
||||
for (auto i = _viewsIncrementRequests.begin(); i != _viewsIncrementRequests.cend(); ++i) {
|
||||
if (i->second == requestId) {
|
||||
_viewsIncrementRequests.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!_viewsToIncrement.empty() && !_viewsIncrementTimer.isActive()) {
|
||||
_viewsIncrementTimer.callOnce(kSendViewsTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) {
|
||||
if (selectingPeer()) {
|
||||
_hider->offerPeer(peerId);
|
||||
|
@ -1505,7 +1404,7 @@ void MainWidget::ui_showPeerHistory(
|
|||
} else {
|
||||
const auto nowActivePeer = _controller->activeChatCurrent().peer();
|
||||
if (nowActivePeer && nowActivePeer != wasActivePeer) {
|
||||
_viewsIncremented.remove(nowActivePeer);
|
||||
session().api().views().removeIncremented(nowActivePeer);
|
||||
}
|
||||
if (isOneColumn() && !_dialogs->isHidden()) {
|
||||
_dialogs->hide();
|
||||
|
|
|
@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "chat_helpers/bot_command.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
@ -201,8 +200,6 @@ public:
|
|||
void ctrlEnterSubmitUpdated();
|
||||
void setInnerFocus();
|
||||
|
||||
void scheduleViewIncrement(HistoryItem *item);
|
||||
|
||||
bool contentOverlapped(const QRect &globalRect);
|
||||
|
||||
void searchInChat(Dialogs::Key chat);
|
||||
|
@ -245,8 +242,6 @@ protected:
|
|||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
private:
|
||||
void viewsIncrement();
|
||||
|
||||
void animationCallback();
|
||||
void handleAdaptiveLayoutUpdate();
|
||||
void updateWindowAdaptiveLayout();
|
||||
|
@ -313,12 +308,6 @@ private:
|
|||
void floatPlayerDoubleClickEvent(
|
||||
not_null<const HistoryItem*> item) override;
|
||||
|
||||
void viewsIncrementDone(
|
||||
QVector<MTPint> ids,
|
||||
const MTPmessages_MessageViews &result,
|
||||
mtpRequestId requestId);
|
||||
void viewsIncrementFail(const MTP::Error &error, mtpRequestId requestId);
|
||||
|
||||
void refreshResizeAreas();
|
||||
template <typename MoveCallback, typename FinishCallback>
|
||||
void createResizeArea(
|
||||
|
@ -389,12 +378,6 @@ private:
|
|||
|
||||
PhotoData *_deletingPhoto = nullptr;
|
||||
|
||||
base::flat_map<not_null<PeerData*>, base::flat_set<MsgId>> _viewsIncremented;
|
||||
base::flat_map<not_null<PeerData*>, base::flat_set<MsgId>> _viewsToIncrement;
|
||||
base::flat_map<not_null<PeerData*>, mtpRequestId> _viewsIncrementRequests;
|
||||
base::flat_map<mtpRequestId, not_null<PeerData*>> _viewsIncrementByRequest;
|
||||
base::Timer _viewsIncrementTimer;
|
||||
|
||||
struct SettingBackground;
|
||||
std::unique_ptr<SettingBackground> _background;
|
||||
|
||||
|
|
Loading…
Reference in New Issue