mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Short poll extended media.
This commit is contained in:
parent
379736a7d1
commit
40bdcd7ebc
8 changed files with 146 additions and 3 deletions
|
@ -20,13 +20,16 @@ namespace {
|
||||||
|
|
||||||
// Send channel views each second.
|
// Send channel views each second.
|
||||||
constexpr auto kSendViewsTimeout = crl::time(1000);
|
constexpr auto kSendViewsTimeout = crl::time(1000);
|
||||||
|
constexpr auto kPollExtendedMediaPeriod = 30 * crl::time(1000);
|
||||||
|
constexpr auto kMaxPollPerRequest = 100;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ViewsManager::ViewsManager(not_null<ApiWrap*> api)
|
ViewsManager::ViewsManager(not_null<ApiWrap*> api)
|
||||||
: _session(&api->session())
|
: _session(&api->session())
|
||||||
, _api(&api->instance())
|
, _api(&api->instance())
|
||||||
, _incrementTimer([=] { viewsIncrement(); }) {
|
, _incrementTimer([=] { viewsIncrement(); })
|
||||||
|
, _pollTimer([=] { sendPollRequests(); }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewsManager::scheduleIncrement(not_null<HistoryItem*> item) {
|
void ViewsManager::scheduleIncrement(not_null<HistoryItem*> item) {
|
||||||
|
@ -52,6 +55,25 @@ void ViewsManager::removeIncremented(not_null<PeerData*> peer) {
|
||||||
_incremented.remove(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() {
|
void ViewsManager::viewsIncrement() {
|
||||||
for (auto i = _toIncrement.begin(); i != _toIncrement.cend();) {
|
for (auto i = _toIncrement.begin(); i != _toIncrement.cend();) {
|
||||||
if (_incrementRequests.contains(i->first)) {
|
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(
|
void ViewsManager::done(
|
||||||
QVector<MTPint> ids,
|
QVector<MTPint> ids,
|
||||||
const MTPmessages_MessageViews &result,
|
const MTPmessages_MessageViews &result,
|
||||||
|
|
|
@ -26,8 +26,22 @@ public:
|
||||||
void scheduleIncrement(not_null<HistoryItem*> item);
|
void scheduleIncrement(not_null<HistoryItem*> item);
|
||||||
void removeIncremented(not_null<PeerData*> peer);
|
void removeIncremented(not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
void pollExtendedMedia(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct PollExtendedMediaRequest {
|
||||||
|
crl::time when = 0;
|
||||||
|
mtpRequestId id = 0;
|
||||||
|
base::flat_set<MsgId> ids;
|
||||||
|
base::flat_set<MsgId> sent;
|
||||||
|
};
|
||||||
|
|
||||||
void viewsIncrement();
|
void viewsIncrement();
|
||||||
|
void sendPollRequests();
|
||||||
|
void sendPollRequests(
|
||||||
|
const base::flat_map<
|
||||||
|
not_null<PeerData*>,
|
||||||
|
QVector<MTPint>> &prepared);
|
||||||
|
|
||||||
void done(
|
void done(
|
||||||
QVector<MTPint> ids,
|
QVector<MTPint> ids,
|
||||||
|
@ -44,6 +58,11 @@ private:
|
||||||
base::flat_map<mtpRequestId, not_null<PeerData*>> _incrementByRequest;
|
base::flat_map<mtpRequestId, not_null<PeerData*>> _incrementByRequest;
|
||||||
base::Timer _incrementTimer;
|
base::Timer _incrementTimer;
|
||||||
|
|
||||||
|
base::flat_map<
|
||||||
|
not_null<PeerData*>,
|
||||||
|
PollExtendedMediaRequest> _pollRequests;
|
||||||
|
base::Timer _pollTimer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -1611,7 +1611,7 @@ std::unique_ptr<HistoryView::Media> MediaInvoice::createView(
|
||||||
message,
|
message,
|
||||||
realParent,
|
realParent,
|
||||||
replacing);
|
replacing);
|
||||||
} else if (!_invoice.extendedPreview.dimensions.isEmpty()) {
|
} else if (_invoice.extendedPreview) {
|
||||||
return std::make_unique<HistoryView::ExtendedPreview>(
|
return std::make_unique<HistoryView::ExtendedPreview>(
|
||||||
message,
|
message,
|
||||||
&_invoice);
|
&_invoice);
|
||||||
|
|
|
@ -63,6 +63,13 @@ struct ExtendedPreview {
|
||||||
QByteArray inlineThumbnailBytes;
|
QByteArray inlineThumbnailBytes;
|
||||||
QSize dimensions;
|
QSize dimensions;
|
||||||
TimeId videoDuration = -1;
|
TimeId videoDuration = -1;
|
||||||
|
|
||||||
|
[[nodiscard]] bool empty() const {
|
||||||
|
return dimensions.isEmpty();
|
||||||
|
}
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Media;
|
class Media;
|
||||||
|
|
|
@ -997,6 +997,9 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session().data().reactions().poll(item, now);
|
session().data().reactions().poll(item, now);
|
||||||
|
if (item->hasExtendedMediaPreview()) {
|
||||||
|
session().api().views().pollExtendedMedia(item);
|
||||||
|
}
|
||||||
_reactionsManager->recordCurrentReactionEffect(
|
_reactionsManager->recordCurrentReactionEffect(
|
||||||
item->fullId(),
|
item->fullId(),
|
||||||
QPoint(0, top));
|
QPoint(0, top));
|
||||||
|
|
|
@ -1169,6 +1169,15 @@ bool HistoryItem::isRegular() const {
|
||||||
return isHistoryEntry() && !isLocal();
|
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() {
|
void HistoryItem::sendFailed() {
|
||||||
Expects(_flags & MessageFlag::BeingSent);
|
Expects(_flags & MessageFlag::BeingSent);
|
||||||
Expects(!(_flags & MessageFlag::SendingFailed));
|
Expects(!(_flags & MessageFlag::SendingFailed));
|
||||||
|
|
|
@ -239,6 +239,7 @@ public:
|
||||||
[[nodiscard]] virtual bool externalReply() const {
|
[[nodiscard]] virtual bool externalReply() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] bool hasExtendedMediaPreview() const;
|
||||||
|
|
||||||
[[nodiscard]] virtual MsgId repliesInboxReadTill() const {
|
[[nodiscard]] virtual MsgId repliesInboxReadTill() const {
|
||||||
return MsgId(0);
|
return MsgId(0);
|
||||||
|
|
|
@ -917,7 +917,7 @@ void HistoryMessageReplyMarkup::updateData(
|
||||||
bool HistoryMessageReplyMarkup::hiddenBy(Data::Media *media) const {
|
bool HistoryMessageReplyMarkup::hiddenBy(Data::Media *media) const {
|
||||||
if (media && (data.flags & ReplyMarkupFlag::OnlyBuyButton)) {
|
if (media && (data.flags & ReplyMarkupFlag::OnlyBuyButton)) {
|
||||||
if (const auto invoice = media->invoice()) {
|
if (const auto invoice = media->invoice()) {
|
||||||
if (!invoice->extendedPreview.dimensions.isEmpty()
|
if (invoice->extendedPreview
|
||||||
&& (!invoice->extendedMedia || !invoice->receiptMsgId)) {
|
&& (!invoice->extendedMedia || !invoice->receiptMsgId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue