mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 12:00:48 +00:00
Short poll extended media.
This commit is contained in:
parent
379736a7d1
commit
40bdcd7ebc
@ -20,13 +20,16 @@ namespace {
|
||||
|
||||
// Send channel views each second.
|
||||
constexpr auto kSendViewsTimeout = crl::time(1000);
|
||||
constexpr auto kPollExtendedMediaPeriod = 30 * crl::time(1000);
|
||||
constexpr auto kMaxPollPerRequest = 100;
|
||||
|
||||
} // namespace
|
||||
|
||||
ViewsManager::ViewsManager(not_null<ApiWrap*> api)
|
||||
: _session(&api->session())
|
||||
, _api(&api->instance())
|
||||
, _incrementTimer([=] { viewsIncrement(); }) {
|
||||
, _incrementTimer([=] { viewsIncrement(); })
|
||||
, _pollTimer([=] { sendPollRequests(); }) {
|
||||
}
|
||||
|
||||
void ViewsManager::scheduleIncrement(not_null<HistoryItem*> item) {
|
||||
@ -52,6 +55,25 @@ void ViewsManager::removeIncremented(not_null<PeerData*> peer) {
|
||||
_incremented.remove(peer);
|
||||
}
|
||||
|
||||
void ViewsManager::pollExtendedMedia(not_null<HistoryItem*> item) {
|
||||
if (!item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
const auto id = item->id;
|
||||
const auto peer = item->history()->peer;
|
||||
auto &request = _pollRequests[peer];
|
||||
if (request.ids.contains(id) || request.sent.contains(id)) {
|
||||
return;
|
||||
}
|
||||
request.ids.emplace(id);
|
||||
if (!request.id && !request.when) {
|
||||
request.when = crl::now() + kPollExtendedMediaPeriod;
|
||||
}
|
||||
if (!_pollTimer.isActive()) {
|
||||
_pollTimer.callOnce(kPollExtendedMediaPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::viewsIncrement() {
|
||||
for (auto i = _toIncrement.begin(); i != _toIncrement.cend();) {
|
||||
if (_incrementRequests.contains(i->first)) {
|
||||
@ -81,6 +103,88 @@ void ViewsManager::viewsIncrement() {
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::sendPollRequests() {
|
||||
const auto now = crl::now();
|
||||
auto toRequest = base::flat_map<not_null<PeerData*>, QVector<MTPint>>();
|
||||
auto nearest = crl::time();
|
||||
for (auto &[peer, request] : _pollRequests) {
|
||||
if (request.id) {
|
||||
continue;
|
||||
} else if (request.when <= now) {
|
||||
Assert(request.sent.empty());
|
||||
auto &list = toRequest[peer];
|
||||
const auto count = int(request.ids.size());
|
||||
if (count < kMaxPollPerRequest) {
|
||||
request.sent = base::take(request.ids);
|
||||
} else {
|
||||
const auto from = begin(request.ids);
|
||||
const auto end = from + kMaxPollPerRequest;
|
||||
request.sent = { from, end };
|
||||
request.ids.erase(from, end);
|
||||
}
|
||||
list.reserve(request.sent.size());
|
||||
for (const auto &id : request.sent) {
|
||||
list.push_back(MTP_int(id.bare));
|
||||
}
|
||||
if (!request.ids.empty()) {
|
||||
nearest = now;
|
||||
}
|
||||
} else if (!nearest || nearest > request.when) {
|
||||
nearest = request.when;
|
||||
}
|
||||
}
|
||||
sendPollRequests(toRequest);
|
||||
if (nearest) {
|
||||
_pollTimer.callOnce(std::max(nearest - now, crl::time(1)));
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::sendPollRequests(
|
||||
const base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
QVector<MTPint>> &batched) {
|
||||
for (auto &[peer, list] : batched) {
|
||||
const auto finish = [=, list = list](mtpRequestId id) {
|
||||
const auto now = crl::now();
|
||||
const auto owner = &_session->data();
|
||||
for (auto i = begin(_pollRequests); i != end(_pollRequests);) {
|
||||
if (i->second.id == id) {
|
||||
const auto peer = i->first->id;
|
||||
for (const auto &itemId : i->second.sent) {
|
||||
if (const auto item = owner->message(peer, itemId)) {
|
||||
owner->requestItemRepaint(item);
|
||||
}
|
||||
}
|
||||
i->second.sent.clear();
|
||||
i->second.id = 0;
|
||||
if (i->second.ids.empty()) {
|
||||
i = _pollRequests.erase(i);
|
||||
} else {
|
||||
i->second.when = now + kPollExtendedMediaPeriod;
|
||||
if (!_pollTimer.isActive()) {
|
||||
_pollTimer.callOnce(kPollExtendedMediaPeriod);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto requestId = _api.request(MTPmessages_GetExtendedMedia(
|
||||
peer->input,
|
||||
MTP_vector<MTPint>(list)
|
||||
)).done([=](const MTPUpdates &result, mtpRequestId id) {
|
||||
_session->api().applyUpdates(result);
|
||||
finish(id);
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId id) {
|
||||
finish(id);
|
||||
}).send();
|
||||
|
||||
_pollRequests[peer].id = requestId;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewsManager::done(
|
||||
QVector<MTPint> ids,
|
||||
const MTPmessages_MessageViews &result,
|
||||
|
@ -26,8 +26,22 @@ public:
|
||||
void scheduleIncrement(not_null<HistoryItem*> item);
|
||||
void removeIncremented(not_null<PeerData*> peer);
|
||||
|
||||
void pollExtendedMedia(not_null<HistoryItem*> item);
|
||||
|
||||
private:
|
||||
struct PollExtendedMediaRequest {
|
||||
crl::time when = 0;
|
||||
mtpRequestId id = 0;
|
||||
base::flat_set<MsgId> ids;
|
||||
base::flat_set<MsgId> sent;
|
||||
};
|
||||
|
||||
void viewsIncrement();
|
||||
void sendPollRequests();
|
||||
void sendPollRequests(
|
||||
const base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
QVector<MTPint>> &prepared);
|
||||
|
||||
void done(
|
||||
QVector<MTPint> ids,
|
||||
@ -44,6 +58,11 @@ private:
|
||||
base::flat_map<mtpRequestId, not_null<PeerData*>> _incrementByRequest;
|
||||
base::Timer _incrementTimer;
|
||||
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
PollExtendedMediaRequest> _pollRequests;
|
||||
base::Timer _pollTimer;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
||||
|
@ -1611,7 +1611,7 @@ std::unique_ptr<HistoryView::Media> MediaInvoice::createView(
|
||||
message,
|
||||
realParent,
|
||||
replacing);
|
||||
} else if (!_invoice.extendedPreview.dimensions.isEmpty()) {
|
||||
} else if (_invoice.extendedPreview) {
|
||||
return std::make_unique<HistoryView::ExtendedPreview>(
|
||||
message,
|
||||
&_invoice);
|
||||
|
@ -63,6 +63,13 @@ struct ExtendedPreview {
|
||||
QByteArray inlineThumbnailBytes;
|
||||
QSize dimensions;
|
||||
TimeId videoDuration = -1;
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return dimensions.isEmpty();
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return !empty();
|
||||
}
|
||||
};
|
||||
|
||||
class Media;
|
||||
|
@ -997,6 +997,9 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
session().data().reactions().poll(item, now);
|
||||
if (item->hasExtendedMediaPreview()) {
|
||||
session().api().views().pollExtendedMedia(item);
|
||||
}
|
||||
_reactionsManager->recordCurrentReactionEffect(
|
||||
item->fullId(),
|
||||
QPoint(0, top));
|
||||
|
@ -1169,6 +1169,15 @@ bool HistoryItem::isRegular() const {
|
||||
return isHistoryEntry() && !isLocal();
|
||||
}
|
||||
|
||||
bool HistoryItem::hasExtendedMediaPreview() const {
|
||||
if (const auto media = _media.get()) {
|
||||
if (const auto invoice = media->invoice()) {
|
||||
return (invoice->extendedPreview && !invoice->extendedMedia);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HistoryItem::sendFailed() {
|
||||
Expects(_flags & MessageFlag::BeingSent);
|
||||
Expects(!(_flags & MessageFlag::SendingFailed));
|
||||
|
@ -239,6 +239,7 @@ public:
|
||||
[[nodiscard]] virtual bool externalReply() const {
|
||||
return false;
|
||||
}
|
||||
[[nodiscard]] bool hasExtendedMediaPreview() const;
|
||||
|
||||
[[nodiscard]] virtual MsgId repliesInboxReadTill() const {
|
||||
return MsgId(0);
|
||||
|
@ -917,7 +917,7 @@ void HistoryMessageReplyMarkup::updateData(
|
||||
bool HistoryMessageReplyMarkup::hiddenBy(Data::Media *media) const {
|
||||
if (media && (data.flags & ReplyMarkupFlag::OnlyBuyButton)) {
|
||||
if (const auto invoice = media->invoice()) {
|
||||
if (!invoice->extendedPreview.dimensions.isEmpty()
|
||||
if (invoice->extendedPreview
|
||||
&& (!invoice->extendedMedia || !invoice->receiptMsgId)) {
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user